[SR-Users] Diameter AVP handling from kamaiio.cfg

Zoltán Miricz zoltan.miricz at gmail.com
Wed Jan 4 19:37:06 CET 2017


Dear All,

I'm wondering is it possible to catch Diameter Messages and their AVP
values from kamailio.cfg just like for SIP messages? (Using pseudo
variables)

I looked into this function from the attached S-CSCF example.

route[REG_MAR_REPLY]
{

#this is async so to know status we have to check the reply avp

xlog("L_DBG","maa_return code is *$avp(s:maa_return_code)*\n");

Sadly it gives back only 1, -1, -2. (which is based on cxdx_mar.c the rc)
What I mainly looking for is the EXPERIMENTAL_RESULT (experimental_rc) and
some different AVP values besides.


Thank you very much in advance!

*Cheers,*
*Zoltan*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20170104/5ec58fb7/attachment.html>
-------------- next part --------------
#!KAMAILIO
#
# This config file implements the basic P-CSCF functionality
#     - web: http://www.kamailio.org
#     - git: http://sip-router.org
#
# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php
# for an explanation of possible statements, functions and parameters.
#
# Direct your questions about this file to: <sr-users at lists.sip-router.org>.
#
# For more information about the various parameters, functions and statements
# try http://sip-router.org/wiki/ .
#

####### Defined Values #########
# *** Value defines - IDs used later in config

# - flags
#       FLT_ - per transaction (message) flags
#       FLB_ - per branch flags

#!define FLT_CAPTURE 1
#!define FLT_DIALOG 2

#!define DLG_TIMEOUT_AVP "i:1"
#!define RR_CUSTOM_USER_AVP "i:2"
#!define DISPATCHER_DST_AVP "i:3"
#!define DISPATCHER_GRP_AVP "i:4"
#!define DISPATCHER_CNT_AVP "i:5"
#!define PDB_CARRIER "i:6"


####### Global Parameters #########

include_file "scscf.cfg"

#!ifdef WITH_DEBUG
debug=5
log_stderror=no
sip_warning=yes
#!else
debug=2
log_stderror=no
sip_warning=no
#!endif

### for foreground operation by FE
fork=no
log_stderror=yes
children=4

alias=HOSTNAME

user_agent_header="User-Agent: Kamailio S-CSCF"
server_header="Server: Kamailio S-CSCF"

/* comment the next line to enable the auto discovery of local aliases
   based on reverse DNS on IPs (default on) */
auto_aliases=no

check_via=no    # (cmd. line: -v)
dns=no          # (cmd. line: -r)
rev_dns=no      # (cmd. line: -R)

# Do SRV-Loadbalancing:
dns_srv_lb=yes
# Always: Also try IPv6:
dns_try_ipv6=yes
# Always prefer IPv6:
dns_cache_flags=6
# DNS-Based failover
use_dns_failover = on
# Query NAPTR-Records as well:
dns_try_naptr=no

#!ifdef WITH_XMLRPC
#!ifndef WITH_TCP
#!define WITH_TCP
#!endif
#!ifndef TCP_PROCESSES
# Number of TCP Processes
#!define TCP_PROCESSES 3
#!endif
#!endif

#!ifdef WITH_TCP
# life time of TCP connection when there is no traffic
# - a bit higher than registration expires to cope with UA behind NAT
tcp_connection_lifetime=3615
#!ifdef TCP_PROCESSES
tcp_children=TCP_PROCESSES
#!endif
#!else
disable_tcp=yes
#!endif

#children=64

system.shutdownmode = 0 desc "System shutdown mode"

# ------------------ module loading ----------------------------------
#mpath="/usr/lib64/kamailio/modules_k/:/usr/lib64/kamailio/modules/:/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/"
# (we try both the lib64 and the lib directory)

loadmodule "tm.so"
loadmodule "pv.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "ims_dialog.so"
loadmodule "textops.so"
loadmodule "maxfwd.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "siputils.so"
loadmodule "kex.so"
#!ifdef DB_URL
loadmodule "presence"
#!endif

#!ifdef DB_URL
loadmodule "db_mysql"
#!ifdef DB_URL2
loadmodule "db_cluster"
#!endif
#!endif

#loadmodule "dispatcher"

loadmodule "enum"
loadmodule "uac"

# Control interfaces:
#loadmodule "ctl"
#loadmodule "cfg_rpc"
#loadmodule "mi_rpc"
#loadmodule "mi_fifo"
#!ifdef WITH_XMLRPC
loadmodule "xmlrpc"
#!endif

loadmodule "cdp.so"
loadmodule "cdp_avp.so"

loadmodule "ims_usrloc_scscf.so"
loadmodule "ims_registrar_scscf.so"
loadmodule "ims_auth.so"
loadmodule "ims_isc.so"

#!ifdef WITH_RO
loadmodule "ims_charging.so"
#!endif

#!ifdef CAPTURE_NODE
loadmodule "siptrace.so"
#!endif

#!ifdef WITH_DEBUG
loadmodule "debugger.so"
#!endif

# ----------------- setting module-specific parameters ---------------
#!ifdef DB_URL2
# ----- db_cluster params -----
modparam("db_cluster", "connection", DB_URL)
modparam("db_cluster", "connection", DB_URL2)
modparam("db_cluster", "cluster", "cluster1=>con1=2s2s;con2=1s1s")
#!endif

# ----- presence params -----
#!ifdef DB_URL
#!ifdef DB_URL2
modparam("presence", "db_url", "cluster://cluster1")
#!else
modparam("presence", "db_url", DB_URL)
#!endif
#modparam("presence", "fallback2db", 1)
modparam("presence", "db_update_period", 20)
#!endif

# ----- mi_fifo params -----
#modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
#modparam("mi_fifo", "fifo_mode", 0666)
#modparam("mi_fifo", "fifo_user", "kamailio")
#modparam("mi_fifo", "fifo_group", "kamailio")

# ----- mi_fifo params -----
#modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
#modparam("mi_fifo", "fifo_mode", 0666)
#modparam("mi_fifo", "fifo_user", "kamailio")
#modparam("mi_fifo", "fifo_group", "kamailio")

# ----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 10sec
modparam("tm", "fr_timer", 10000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)
# Don't reply automatically with "100 Trying"
modparam("tm", "auto_inv_100", 0)

# ----- rr params -----
# add value to ;lr param to cope with most of the UAs
modparam("rr", "enable_full_lr", 1)
# append from tag to the RR
modparam("rr", "append_fromtag", 1)
# add a Username to RR-Header
modparam("rr", "add_username", 1)
# Take User from a custom AVP
modparam("rr", "custom_user_avp", "$avp(RR_CUSTOM_USER_AVP)")

# -- usrloc params --
modparam("ims_usrloc_scscf", "enable_debug_file", 0)
modparam("ims_usrloc_scscf", "matching_mode", 0)
modparam("ims_registrar_scscf", "max_contacts", 5);
#!ifdef DB_URL
#!ifdef DB_URL2
modparam("ims_usrloc_scscf", "db_url", "cluster://cluster1")
#!else
modparam("ims_usrloc_scscf", "db_url", DB_URL)
#!endif
modparam("ims_usrloc_scscf", "db_mode", 1)
#!endif
modparam("ims_registrar_scscf", "default_expires",  604800)
modparam("ims_registrar_scscf", "min_expires", 3600)
modparam("ims_registrar_scscf", "max_expires",  604800)
modparam("ims_registrar_scscf", "subscription_default_expires", 654800)
modparam("ims_registrar_scscf", "subscription_min_expires", 3700)
modparam("ims_registrar_scscf", "subscription_max_expires", 605800)

# -- CDP params --
modparam("cdp","config_file","/etc/kamailio_scscf/scscf.xml")

# -- ims_dialog params --
modparam("ims_dialog", "dlg_flag", FLT_DIALOG)
modparam("ims_dialog", "timeout_avp", "$avp(DLG_TIMEOUT_AVP)")
modparam("ims_dialog", "detect_spirals", 1)
modparam("ims_dialog", "profiles_no_value", "orig ; term")

#!ifdef WITH_XMLRPC
# ----- xmlrpc params -----
modparam("xmlrpc", "route", "XMLRPC");
modparam("xmlrpc", "url_match", "^/RPC")
#!endif

#!ifdef WITH_DEBUG
# ----- debugger params -----
modparam("debugger", "cfgtrace", 1)
#!endif

#!ifdef CAPTURE_NODE
# Destination, where to send the traffic
modparam("siptrace", "duplicate_uri", CAPTURE_NODE)
# Trace all traffic
modparam("siptrace", "trace_on", 1)
modparam("siptrace", "trace_to_database", 0)
modparam("siptrace", "trace_flag", FLT_CAPTURE)
modparam("siptrace", "hep_mode_on", 1)
#!endif

# -- ims_auth params --
modparam("ims_auth", "name", URI)
modparam("ims_auth", "registration_default_algorithm", REG_AUTH_DEFAULT_ALG)
#!ifdef CXDX_FORCED_PEER
modparam("ims_auth", "cxdx_forced_peer", CXDX_FORCED_PEER)
#!endif
modparam("ims_auth", "cxdx_dest_realm", NETWORKNAME)
modparam("ims_auth", "av_check_only_impu", 1)

# -- ims_registrar_scscf params --
#!ifdef WITH_DEBUG
modparam("ims_registrar_scscf", "default_expires", 60)
modparam("ims_registrar_scscf", "min_expires", 60)
modparam("ims_registrar_scscf", "max_expires", 60)
#!else
modparam("ims_registrar_scscf", "default_expires",  604800)
modparam("ims_registrar_scscf", "min_expires", 3600)
modparam("ims_registrar_scscf", "max_expires",  604800)
#!endif
modparam("ims_registrar_scscf", "use_path", 1)
modparam("ims_registrar_scscf", "support_wildcardPSI",1)
modparam("ims_registrar_scscf", "user_data_xsd","/etc/kamailio_scscf/CxDataType_Rel7.xsd")
modparam("ims_registrar_scscf", "scscf_name", URI)
modparam("ims_registrar_scscf", "cxdx_dest_realm", NETWORKNAME)

# ----- ims_isc params -----
modparam("ims_isc", "my_uri", HOSTNAME)

#!ifdef WITH_RO
# ----- ims_diameter_ro params -----
modparam("ims_charging", "origin_host", HOSTNAME);
modparam("ims_charging", "origin_realm", NETWORKNAME);
#!ifdef RO_FORCED_PEER
modparam("ims_charging", "ro_forced_peer", RO_FORCED_PEER);
#!endif
modparam("ims_charging", "destination_host", RO_DESTINATION);
modparam("ims_charging", "destination_realm", NETWORKNAME);

modparam("ims_charging","service_context_id_root", RO_ROOT);
modparam("ims_charging","service_context_id_ext", RO_EXT);
modparam("ims_charging","service_context_id_mnc", RO_MNC);
modparam("ims_charging","service_context_id_mcc", RO_MCC);
modparam("ims_charging","service_context_id_release", RO_RELEASE);

modparam("ims_charging","interim_update_credits",30);
modparam("ims_charging","timer_buffer",5);
#!endif

# ----- enum params -----
modparam("enum", "domain_suffix", ENUM_SUFFIX)

# ----- sanity params -----
modparam("sanity", "autodrop", 0)

# -- presence params --
modparam("presence", "subs_remove_match", 1)   #means we match subscriptions on all attributes

# ----------------- Settings for Dispatcher ---------------
#modparam("dispatcher", "list_file", "/etc/kamailio_scscf/dispatcher.list")
# Dispatcher: Enable Failover-Support
#modparam("dispatcher", "flags", 2)
# Dispatcher: Overwrite Destination address, if required.
#modparam("dispatcher", "force_dst", 1)
# AVP's required for Fail-Over-Support:
#modparam("dispatcher", "dst_avp", "$avp(DISPATCHER_DST_AVP)")
#modparam("dispatcher", "grp_avp", "$avp(DISPATCHER_GRP_AVP)")
#modparam("dispatcher", "cnt_avp", "$avp(DISPATCHER_CNT_AVP)")
# Try to recover disabled destinations every 15 seconds.
#modparam("dispatcher", "ds_ping_interval", 15)
# Actively query the gateways:
#modparam("dispatcher", "ds_probing_mode", 1)

####### Routing Logic ########
# Main SIP request routing logic
# - processing of any incoming SIP request starts with this route

route {

#trace every request
  xlog("L_WARN", "S-CSCF:[$rm] from [$fu] to [$tu]\n");

# xlog("L_INFO", "$rm ($fu ($si:$sp) to $tu, $ci)\n");

#!ifdef WITH_DEBUG
        xlog("L_ERR", "$rm ($fu ($si:$sp) to $tu, $ci)\n");
#!endif

        # per request initial checks
        route(REQINIT);

        # Handle Registrations:
        if (is_method("REGISTER")) {
                route(REGISTER);
                exit;
        }

        # we need to support subscription to reg event
        if (is_method("SUBSCRIBE") && search("^(Event|o)([ \t]*):([ \t]*)reg")) {
                route(SUBSCRIBE);
                break;
        }

        if (is_method("PUBLISH") && search("^(Event|o)([ \t]*):([ \t]*)reg")) {
                route(PUBLISH);
                break;
        }

        #Set DLG flag to track dialogs using dialog2
        if (!is_method("REGISTER|SUBSCRIBE"))
                setflag(FLT_DIALOG);

        # Evaluate Route-Header and set $route_uri
        loose_route();

        if (is_method("CANCEL|ACK")) {
                t_relay();
                exit;
        }

        if (($route_uri =~ "sip:orig@"+HOSTNAME_ESC+".*") || isc_from_as("orig")) {
                # we need something like this to assign SCSCF to unregistered user for services
                # support for AS origination on behalf of unregistered useri
                # can use the registrar is_registered methods - must see if we need to check orig or term?

                # Originating
                route(orig);
                break;
        } else {
                isc_from_as("term");
                if ($retcode == -2) {
                        # Treat as originating, since it was retargeted:
                        route(orig);
                        break;
                }
                if ((is_in_profile("orig") || has_totag()) && ($route_uri =~ "sip:mo@"+".*")) {
                        route(orig_subsequent);
                        break;
                }
                if ((is_in_profile("term") || has_totag()) && ($route_uri =~ "sip:mt@"+".*")) {
                        route(term_subsequent);
                        break;
                }

                # Terminating
                if (uri=~"sip:(.*)@"+NETWORKNAME_ESC +"(.*)" || uri=~"tel:.*") {
                        if (!term_impu_registered("location")) {
                                xlog("L_WARN", "S-CSCF: We need to do an UNREG server SAR assignemnt");
                                assign_server_unreg("UNREG_SAR_REPLY", "location", "term");
                                exit;
                        }
                } else {
                        sl_send_reply("403","Forbidden - Dialog not found on S-CSCF or Terminating user not suitable for unregistered services");
                        exit();
                }
                route(term);
                break;
        }
}

route[UNREG_SAR_REPLY]
{
        xlog("L_WARN","S-CSCF: UNREG: saa_return code is $avp(s:saa_return_code)\n");
        switch ($avp(s:saa_return_code)){
            case 1: #success
                    xlog("L_WARN", "S-CSCF: SAR success - will route message\n");
                route(term);
                break;
            case -1: #failure
                    xlog("L_ERR", "S-CSCF: SAR failure - error response sent from module\n");
                break;
            case -2: #error
                    xlog("L_ERR", "S-CSCF: SAR error - error response sent from module\n");
                break;
            default:
                    xlog("L_ERR", "S-CSCF: Unknown return code from SAR, value is [$avp(s:saa_return_code)]\n");
                break;
        }
        exit;
}


######################################################################
# Helper routes (Basic-Checks, NAT-Handling/RTP-Control, XML-RPC)
######################################################################
# Per SIP request initial checks
route[REQINIT] {
        # Trace this message
#!ifdef CAPTURE_NODE
        sip_trace();
        setflag(FLT_CAPTURE);
#!endif

        if (!mf_process_maxfwd_header("10")) {
                sl_send_reply("483","Too Many Hops");
                exit;
        }

        if(!sanity_check("1511", "7")) {
                xlog("Malformed SIP message from $si:$sp\n");
                exit;
        }

        # Check for shutdown mode:
        if (!has_totag() && ($sel(cfg_get.system.shutdownmode) > 0)) {
                send_reply("503", "Server shutting down");
                exit;
        }

        # Reply to OPTIONS:
        if (is_method("OPTIONS") && (uri==myself)) {
                options_reply();
                exit;
        }

        # Ignore Re-Transmits:
        if (t_lookup_request()) {
                exit;
        }
        if (is_method("INVITE")) {
                send_reply("100", "Trying");
        }

}


######################################################################
# Publish route
######################################################################
route[PUBLISH]
{
        if (!t_newtran()) {
                #absorb retransmissions
                sl_reply("500","Could not create transaction");
                exit;
        }

        if (can_publish_reg("location")) {
                $var(ret)= publish_reg("location");
                switch ($var(ret)){
                        case 1: #success
                                xlog("L_DBG", "S-CSCF: Publish reg successful");
                                break;
                        case -1: #failure
                                xlog("L_ERR", "S-CSCF: Publish reg failure - sending 500 Error now\n");
                                t_reply("500","Server Error publishing subscription");
                                break;
                        default:
                                xlog("L_ERR", "S-CSCF: Unknown return code from publish reg event alue is [$var(ret)]\n");
                                break;
                }
        } else {
                t_reply("403","Forbidden to PUBLISH");
                exit;
        }
}

######################################################################
# Subscribe route
######################################################################
route[SUBSCRIBE]
{
        if (!t_newtran()) {
                #absorb retransmissions
                sl_reply("500","Could not create transaction");
                exit;
        }

        if (!has_totag()) {
                xlog("L_DBG", "This is an initial SUBSCRIBE\n");
                if (!term_impu_registered("location")) {
                        xlog("L_DBG", "We need to do an UNREG server SAR assignment\n");
                        assign_server_unreg("SUBSCRIBE_UNREG_SAR_REPLY", "location", "term");
                        exit;
                }
                if (!can_subscribe_to_reg("location")){
                        t_reply("403","Forbidden to SUBSCRIBE");
                        exit;
                }
        }else{
                xlog("L_DBG", "This is a subsequent SUBSCRIBE\n");
        }

        $var(ret)= subscribe_to_reg("location");
        switch ($var(ret)){
                case 1: #success
                        xlog("L_DBG", "S-CSCF: Subscribe to reg successful");
                        break;
                case -1: #failure
                        xlog("L_ERR", "S-CSCF: Subscribe to reg failure - sending 500 Error now\n");
                        t_reply("500","Server Error saving subscription");
                        break;
                case -2: #error
                        xlog("L_ERR", "S-CSCF: Subscribe to reg error sending notify - 200 OK so subscription already sent\n");
                        break;
                default:
                        xlog("L_ERR", "S-CSCF: Unknown return code from subscribe to reg event alue is [$var(ret)]\n");
                        break;
        }
}

route[SUBSCRIBE_UNREG_SAR_REPLY]
{

        xlog("L_DBG","S-CSCF: saa_return code is $avp(s:saa_return_code)\n");
        switch ($avp(s:saa_return_code)){
                case 1: #success
                        xlog("L_DBG", "S-CSCF: SAR success - will process subscribe\n");
                        if (can_subscribe_to_reg("location")){
                                $var(ret)= subscribe_to_reg("location");
                                switch ($var(ret)){
                                case 1: #success
                                        xlog("L_WARN", "S-CSCF: Subscribe to reg successful");
                                        break;
                                case -1: #failure
                                        xlog("L_ERR", "S-CSCF: Subscribe to reg failure - sending 500 Error now\n");
                                        t_reply("500","Server Error saving subscription");
                                        break;
                                case -2: #error
                                        xlog("L_ERR", "S-CSCF: Subscribe to reg error sending notify - 200 OK so subscription already sent\n");
                                        break;
                                default:
                                        xlog("L_ERR", "S-CSCF: Unknown return code from subscribe to reg event alue is [$var(ret)]\n");
                                        break;
                                }
                        }else{
                                t_reply("403","Forbidden to SUBSCRIBE");
                                exit;
                        }
                        break;
                case -1: #failure
                        xlog("L_ERR", "S-CSCF: SAR failure - Sending 403 Forbidden\n");
                        t_reply("403","Forbidden to SUBSCRIBE");
                        break;
                case -2: #error
                        xlog("L_ERR", "S-CSCF: SAR error - Sending 403 Forbidden\n");
                        t_reply("403","Forbidden to SUBSCRIBE");
                        break;
                default:
                        xlog("L_ERR", "S-CSCF: Unknown return code from SAR, value is [$avp(s:saa_return_code)] - sending 403 Forbidden\n");
                        t_reply("403","Forbidden to SUBSCRIBE");
                        break;
        }
        exit;
}

######################################################################
# XMLRPC routing
######################################################################
#!ifdef WITH_XMLRPC
route[XMLRPC] {
        if ((method=="POST" || method=="GET")
#!ifdef XMLRPC_WHITELIST_1
&& ((src_ip == XMLRPC_WHITELIST_1)
#!ifdef XMLRPC_WHITELIST_2
 || (src_ip == XMLRPC_WHITELIST_2)
#!endif
#!ifdef XMLRPC_WHITELIST_3
 || (src_ip == XMLRPC_WHITELIST_3)
#!endif
)
#!endif
) {
                # close connection only for xmlrpclib user agents (there is a bug in
                # xmlrpclib: it waits for EOF before interpreting the response).
                if ($hdr(User-Agent) =~ "xmlrpclib")
                        set_reply_close();
                set_reply_no_connect();
                dispatch_rpc();
                exit;
        }
        send_reply("403", "Forbidden");
        exit;
}
#!endif

######################################################################
# Route for handling Registrations:
######################################################################
route[REGISTER] {
        if (!ims_www_authenticate(NETWORKNAME)) {
                if ($? == -2) {
                        t_reply("403", "Authentication Failed");
                        exit;
                } else if ($? == -3) {
                        t_reply("400", "Bad Request");
                        exit;
                } else {
                        #user has not been authenticated. Lets send a challenge via 401 Unauthorized
                        xlog("L_DBG","About to challenge! auth_ims\n");
                        ims_www_challenge("REG_MAR_REPLY", "$td");
                        exit;
                }
        } else {
                xlog("L_DBG", "Auth succeeded\n");
                # We need to check if this user is registered or not
                if (!impu_registered("location")) {
                        #xlog("L_ERR", "Not REGISTERED\n");
                        xlog("L_WARN", "S-CSCF: User REGISTERED: $fu via ($si:$sp)\n");
                        save("PRE_REG_SAR_REPLY","location");
                        exit;
                } else {
                        isc_match_filter_reg("1","location");
                        save("REG_SAR_REPLY","location");
                        exit;
                }
        }
}

route[REG_MAR_REPLY]
{
     #this is async so to know status we have to check the reply avp
     #xlog("L_WARN","S-CSCF: maa_return code is $avp(s:maa_return_code)\n");
     switch ($avp(s:maa_return_code)){
             case 1: #success
                     xlog("L_WARN", "S-CSCF: MAR success - 401/407 response sent from module\n");
                     break;
             case -1: #failure
                     xlog("L_ERR", "S-SCSF: MAR failure - error response sent from module\n");
                     break;
             case -2: #error
                     xlog("L_ERR", "S-CSCF: MAR error - sending error response now\n");
                     t_reply("500", "MAR failed");
                     break;
             default:
                     xlog("L_ERR", "S-CSCF: Unknown return code from MAR, value is [$avp(s:uaa_return_code)]\n");
                     t_reply("500", "Unknown response code from MAR");
                     break;
     }
     exit;
}

route[PRE_REG_SAR_REPLY]
{
    xlog("L_DBG","S-CSCF: saa_return code is $avp(s:saa_return_code)\n");
        #this is async so to know status we have to check the reply avp
    #xlog("L_WARN","S-CSCF: saa_return code (for scscf_save on register) is $avp(s:saa_return_code)\n");
    switch ($avp(s:saa_return_code)){
            case 1: #success
                   xlog("L_WARN", "S-CSCF: SAR success - 200 response sent from module\n");
                    isc_match_filter_reg("0","location");
                    exit;
            case -1: #failure
                    xlog("L_ERR", "S-CSCF: SAR failure - error response sent from module\n");
                    break;
            case -2: #error
                    xlog("L_ERR", "S-CSCF: SAR error - error response sent from module\n");
                    break;
            default:
                    xlog("L_ERR", "S-CSCF: Unknown return code from SAR, value is [$avp(s:uaa_return_code)]\n");
                    break;
    }
    exit;
}

route[REG_SAR_REPLY]
{
    xlog("L_DBG","saa_return code is $avp(s:saa_return_code)\n");
    #this is async so to know status we have to check the reply avp
    #xlog("L_WARN","S-CSCF: saa_return code (for scscf_save on register) is $avp(s:saa_return_code)\n");
    switch ($avp(s:saa_return_code)){
            case 1: #success
                   xlog("L_WARN", "S-CSCF: SAR success - 200 response sent from module\n");
                    exit;
            case -1: #failure
                    xlog("L_ERR", "S-CSCF: SAR failure - error response sent from module\n");
                    break;
            case -2: #error
                    xlog("L_ERR", "S-CSCF: SAR error - error response sent from module\n");
                    break;
            default:
                    xlog("L_ERR", "S-CSCF: Unknown return code from SAR, value is [$avp(s:uaa_return_code)]\n");
                    break;
    }
    exit;
}

######################################################################
# Apply privacy, if requested
######################################################################
route[apply_privacy]
{
        if (is_present_hf("Privacy") && ($hdr(Privacy)=="id")) {
                remove_hf("P-Asserted-Identity");
        }
}

######################################################################
# Originating, Intial Requests
######################################################################
route[orig]
{
        xlog("L_DBG","Enter orig route\n");
        set_dlg_profile("orig");

        # we MAYBE need something like this to check if a user is barred
        # if (S_originating_barred()){
                # sl_send_reply("403","Forbidden - Originating Public Identity barred");
                # exit;
        # }
        if (is_method("INVITE|SUBSCRIBE")) {
                $avp(RR_CUSTOM_USER_AVP)="mo";
                record_route();
        }

        # Start new transaction:
        t_newtran();

        # check if dialog saved as fwded to AS
        if (isc_match_filter("orig", "location")) {
                t_on_failure("isc_orig_failure");
                #xlog("Orig - msg was fwded to AS\n");
                exit;
        }

        if (!isc_from_as("orig")) {
                remove_hf("P-Asserted-Identity");
                append_hf("P-Asserted-Identity: <sip:$fU@$fd>\r\n");
        }

#!ifdef WITH_RO
        # before we allow call - lets check credit
        if (is_method("INVITE")) {
                xlog("L_DBG","Sending initial CCR Request for call\n");
                $var(cc_ret) = Ro_CCR("CHARGING_CCR_REPLY", "orig", 30, "0", "0");
                if ($var(cc_ret) < 0) {
                        xlog("L_ERR","S-CSCF: CCR Request failure\n");
                        sl_send_reply("402","Payment required");
                        exit;
                }
                xlog("L_DBG","CCR Request success\n");
                exit;
        }
#!endif
        route(Finalize_Orig);
}

route[Finalize_Orig]
{
        # Check for PSTN destinations:
        if (is_method("INVITE")) {
                route(PSTN_handling);
        }

        t_on_reply("orig_reply");

        t_relay();
}

route[CHARGING_CCR_REPLY]
{
        xlog("L_DBG","saa_return code is $avp(s:cca_return_code)\n");

        switch ($avp(s:cca_return_code)){
            case 1: #success
                xlog("L_DBG", "CCR success - will route message\n");
                route(Finalize_Orig);
                break;
            case -1: #failure
                xlog("L_ERR", "S-CSCF: CCR failure - error response sent from module\n");
                send_reply("402","Payment required");
                break;
            case -2: #error
                xlog("L_ERR", "S-CSCF: CCR error - error response sent from module\n");
                send_reply("500", "Charging Error");
                break;
            default:
                xlog("L_ERR", "S-CSCF: Unknown return code from CCR: [$avp(s:cca_return_code)] \n");
                send_reply("500", "Charging Error");
                break;
        }
        exit;
}


######################################################################
# Replies to the Initial Requests
######################################################################
onreply_route[orig_reply]
{
        xlog("L_WARN", "S-CSCF TEST: $C(xb) [$rm] from [$fu] to [$tu] $C(xx) \n");
        xlog("L_DBG","Orig reply\n");

        route(apply_privacy);
        break;
}

######################################################################
# Originating, subsequent requests
######################################################################
route[orig_subsequent]
{
        xlog("L_WARN", "S-CSCF TEST2: $C(xb) [$rm] from [$fu] to [$tu] $C(xx) \n");
        xlog("L_DBG","Orig_Subsequent\n");

        if (!is_method("ACK")) {
                t_on_reply("orig_subsequent_reply");
        }
        t_relay();
}

######################################################################
# Replies for originating, subsequent requests
######################################################################
onreply_route[orig_subsequent_reply]
{
        xlog("L_DBG","Orig_Subsequent_reply\n");
        route(apply_privacy);
        break;
}

######################################################################
# Failure-Route for Requests to an AS
######################################################################
failure_route[isc_orig_failure]
{
        xlog("L_DBG","ISC_Orig_failure\n");

        if (t_check_status("(408)|(5..)")){
                t_on_failure("isc_orig_failure");
                if (isc_match_filter("orig","location")){
                        xlog("L_DBG","ISC_Orig_failure - msg was fwded to AS\n");
                        exit;
                }

                if (isc_from_as("origfail")) {
                        remove_hf("P-Asserted-Identity");
                        append_hf("P-Asserted-Identity: <sip:$fU@$fd>\r\n");
                }

                t_on_reply("orig_reply");

                t_relay();
        }
}

######################################################################
# Terminating requests
######################################################################
route[term]
{
        xlog("L_DBG","Term\n");

        set_dlg_profile("term");

        #we need something like this to check if a user is barred
        # if (S_terminating_barred()){
                # sl_send_reply("404","Not Found - Terminating user barred");
                # exit;
        # }

        if (is_method("INVITE|SUBSCRIBE")) {
                $avp(RR_CUSTOM_USER_AVP)="mt";
                $avp(i:20)="mt";
                record_route();
        }

        # check if dialog saved as fwded to AS
        if (isc_match_filter("term","location")){
                t_on_failure("isc_term_failure");
                xlog("L_DBG","Term - msg was fwded to AS\n");
                exit;
        }

        if (lookup("location")) {
                if (uri=~"sip:(.*)@"+NETWORKNAME_ESC+"(.*)") {
                        if (!t_newtran()) {
                                sl_reply_error();
                                exit;
                        }
                        t_reply("404","Not Found - destination user not found on this S-CSCF");
                        exit;
                }
        } else {
                # User not registered? Reply with 404.
                if (!t_newtran()) {
                        sl_reply_error();
                        exit;
                }
                t_reply("404","Not Found - destination user not found on this S-CSCF");
                exit;
        }
        route(apply_privacy);

        t_relay();
}


######################################################################
# Failure Route for Terminating requests
######################################################################
failure_route[isc_term_failure]
{
        xlog("L_DBG","ISC_term_failure\n");

        if (t_check_status("(408)|(5..)")){
                t_on_failure("isc_term_failure");
                if (isc_match_filter("term","location")){
                        xlog("L_DBG","Term - msg was fwded to AS\n");
                        exit;
                }

                if (lookup("location")) {
                        if (uri=~"sip:(.*)"+NETWORKNAME_ESC+"(.*)"){
                                t_reply("404","Not Found - destination user not found on this S-CSCF");
                                exit;
                        }
                } else {
                        t_reply("404","Not Found - destination user not found on this S-CSCF");
                        exit;
                }
                t_relay();
        }
}

######################################################################
# Terminating, subsequent requests
######################################################################
route[term_subsequent]
{
        xlog("L_DBG","term_subsequent\n");
        route(apply_privacy);
        t_relay();
}

######################################################################
# Check for PSTN destinations:
######################################################################
route[PSTN_handling]
{
        # First, we translate "tel:"-URI's to SIP-URI's:
        # $ru:           tel:+(34)-999-888-777
        # $fu:           sip:test at foo.com
        # becomes $ru:   sip:+34999888777 at foo.com;user=phone
        if (!tel2sip("$ru", "$fd", "$ru"))
                xlog("L_WARN","S-CSCF: Failed to convert $ru to a sip:-URI - M=$rm R=$ru F=$fu T=$tu IP=$si:$sp ID=$ci\n\n");

        if ($rU =~ "\+[0-9]+") {
                # Now let's check, if the number can be found in ENUM:
                if(!enum_query()) {
                        # ENUM failed, send it to the PSTN-Gateway:
                        route(PSTN);
                        break;
                }
        }
}

######################################################################
# Send calls to the PSTN-Gateways:
######################################################################
route[PSTN]
{
#       if (!ds_select_domain("1", "4")) {
#               xlog("L_WARN","No PSTN-Gateways available - M=$rm R=$ru F=$fu T=$tu IP=$si:$sp ID=$ci\n\n");
#               send_reply("503", "Service not available");
#               exit;
#       }
        # Relay the request:
        t_on_failure("PSTN_failure");

        t_relay();
        exit;
}

######################################################################
# manage failure routing cases, perform failover
######################################################################
failure_route[PSTN_failure] {
        # Choose another gateway, in case we
        # - get a local generated "408"
        # - receive a 5xx or 6xx reply from the proxy.
        if (t_branch_timeout() || t_check_status("[5-6]..")) {
#               if (ds_next_domain()) {
                        # Do Failover in case problems:
#                       t_on_failure("PSTN_failure");
#                       t_relay();
#               } else {
                        # Add a header, to indicate the phone should try again in 30 seconds.
                        append_hf("Retry-After: 30\r\n");
                        send_reply("503", "Service not available");
                }
                exit;
        }
#}



More information about the sr-users mailing list