Login | Register

Documentation

Documentation -> Tutorials -> Using the Script Helper module

This page has been visited 5684 times.


1.  Tutorial Overview

The purpose of this new module is to help you start in an easy way with the OpenSIPS script. The learning curve gets milder as the beginners can start with a simplified format of the script - the idea is to shift the main focus on routing the SIP initial requests (which define the service logic), while transparently handling a lot of "standard" SIP scripting logic, in order to both save script coding time and mitigate potential SIP scripting errors. This tutorial offers both a brief overview on the features of the new module and an example script.

2.  Current features

As stated in the documentation, the module currently features:

  1. transparent handling of SIP sequential requests
    • sequential requests are properly and silently handled - they will not hit the script at all anymore
    • for initial SIP requests, the module performs record-routing (i.e. OpenSIPS adds itself in the signaling path using a Record-Route header), after which the main route is triggered, just as before
    • for sequential SIP requests, the module is automatically doing loose_route() for proper routing.
    • optionally a special route may be run just before all sequential requests are routed out
  2. automatic dialog support
    • automatically create dialog support for the INVITE-based sessions
    • for sequential requests within a dialog, a complete dialog matching (Call-ID, From-tag, To-tag) will be attempted if the quick 'did'-based Record-Route parameter matching fails


Future directions for the module include adding authentication and NAT support.

3.  Example script

SIP logic provided:

  • initial and sequential SIP request routing (using the script helper)
  • dialog support (using the script helper)
  • also acts as a SIP registrar



Table: Scripting examples

With Script HelperClassic Script
####### Global Parameters #########

debug = 3

# log to syslog by default
log_stderror = no
log_facility = LOG_LOCAL0

fork = yes
children = 5
tcp_children = 1

# comment the next line to enable the auto discovery of local aliases
# based on reverse DNS on IPs
auto_aliases = no

listen = udp:192.168.2.133:5060 use_children 8

disable_tcp = no
disable_tls = no

exec_msg_threshold = 200000

####### Modules Section ########

mpath = "/usr/local/lib/opensips/modules/"

loadmodule "signaling.so"                                                                 

#### Stateless module
loadmodule "sl.so"

#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 10)
modparam("tm", "fr_inv_timeout", 40)

loadmodule "rr.so"
modparam("rr", "append_fromtag", 0)

loadmodule "maxfwd.so"
loadmodule "sipmsgops.so"

#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")

loadmodule "db_mysql.so"
modparam("db_mysql", "exec_query_threshold", 200000)

loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)

loadmodule "dialog.so"
modparam("dialog", "db_url", "mysql://opensips:XXXXXXXXX@192.168.2.133/opensips")
modparam("dialog", "db_mode", 1)
modparam("dialog", "default_timeout", 3600)
modparam("dialog", "ping_interval", 5)

loadmodule "usrloc.so"
modparam("usrloc", "db_mode",   1)
modparam("usrloc", "db_url",    "mysql://opensips:XXXXXXXXX@192.168.2.133/opensips")

loadmodule "registrar.so"
loadmodule "script_helper.so"

# this route will be run right before sequential requests are routed out
modparam("script_helper", "sequential_route", "my_seq_route")
modparam("script_helper", "use_dialog", 1)
modparam("script_helper", "create_dialog_flags", "PpB")

route [my_seq_route]
{
    xlog("---- Sequential request handler ---- \n");
    xlog("$rm | Call-ID: $ci | FT: $ft | TT: $tt\n");
}
# main request routing logic
route
{
    $T_fr_timeout = 8;
    $T_fr_inv_timeout = 30;

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


























































    if (!uri == myself)
    {
        append_hf("P-hint: outbound\r\n");
        route(relay);
    }




    if (is_method("PUBLISH|SUBSCRIBE"))
    {
        sl_send_reply("503", "Service Unavailable");
        exit;
    }

    if (is_method("REGISTER"))
    {
        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",""))
    {
        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_failure("failed_call");

    if (!t_relay())
        send_reply("500", "Internal Error");

    exit;
}

failure_route [failed_call]
{
    if (t_was_cancelled())
        exit;

    if (next_branches())
    {
        t_on_failure("failed_call");
        t_relay();
    }
}
####### Global Parameters #########

debug = 3

# log to syslog by default
log_stderror = no
log_facility = LOG_LOCAL0

fork = yes
children = 5
tcp_children = 1

# comment the next line to enable the auto discovery of local aliases
# based on reverse DNS on IPs
auto_aliases = no

listen = udp:192.168.2.133:5060 use_children 8

disable_tcp = no
disable_tls = no

exec_msg_threshold = 200000

####### Modules Section ########

mpath = "/usr/local/lib/opensips/modules/"

loadmodule "signaling.so"                                                                 

#### Stateless module
loadmodule "sl.so"

#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 10)
modparam("tm", "fr_inv_timeout", 40)

loadmodule "rr.so"
modparam("rr", "append_fromtag", 0)

loadmodule "maxfwd.so"
loadmodule "sipmsgops.so"

#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")

loadmodule "db_mysql.so"
modparam("db_mysql", "exec_query_threshold", 200000)

loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)

loadmodule "dialog.so"
modparam("dialog", "db_url", "mysql://opensips:XXXXXXXXX@192.168.2.133/opensips")
modparam("dialog", "db_mode", 1)
modparam("dialog", "default_timeout", 3600)
modparam("dialog", "ping_interval", 5)

loadmodule "usrloc.so"
modparam("usrloc", "db_mode",   1)
modparam("usrloc", "db_url",    "mysql://opensips:XXXXXXXXX@192.168.2.133/opensips")

loadmodule "registrar.so"














# main request routing logic
route
{
    $T_fr_timeout = 8;
    $T_fr_inv_timeout = 30;

    if (!mf_process_maxfwd_header("10"))
    {
        sl_send_reply("483","Too Many Hops");
        exit;
    }
    if (has_totag())
    {
        if (loose_route() || match_dialog())
        {
            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();
            }

            xlog("---- Sequential request handler ---- \n");
            xlog("$rm | Call-ID: $ci | FT: $ft | TT: $tt\n");

            # 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();

    # record routing
    if (!is_method("REGISTER|MESSAGE"))
        record_route();
    if (!uri == myself)
    {
        append_hf("P-hint: outbound\r\n");
        route(relay);
    }

    if (is_method("INVITE") && !has_totag())
        create_dialog("PpB");

    if (is_method("PUBLISH|SUBSCRIBE"))
    {
        sl_send_reply("503", "Service Unavailable");
        exit;
    }

    if (is_method("REGISTER"))
    {
        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",""))
    {
        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_failure("failed_call");

    if (!t_relay())
        send_reply("500", "Internal Error");

    exit;
}

failure_route [failed_call]
{
    if (t_was_cancelled())
        exit;

    if (next_branches())
    {
        t_on_failure("failed_call");
        t_relay();
    }
}

Page last modified on April 07, 2014, at 12:00 PM