1

I followed tutorial on https://www.powerpbx.org/content/opensips-v24-debian-v8-mariadb-apache-v1

With minor tweaks for "Debian Buster" I have installed all components, services starts with no error, I created few subscribers from opensipscp, under alias I added DID number pointing username of sip device, under routing added dr_gateway with type 1 and added ip address of DID provider trunk.

Inbound calls are fine. Then I added IP's for my outbound trunks, set gateway type - 2 Added rules to include all outbound gateways for prefix starting 353 In dialplan I have added rule to translate from local format to E164, but it seem to not work

I can't get my head around how to succeed with outbound calls, I have spent whole weekend digging trough opensips documentation page and the book "Building Telephony Systems with OpenSIPS Second Edition" by Flavio-E.-Goncalves over and over again.

Here is debug output form opensips during call

DBG:dialplan:dp_translate_f: dpid is 10 partition is default
Dec 22 23:39:26 [892] DBG:dialplan:dp_get_svalue: searching 15
Dec 22 23:39:26 [892] DBG:dialplan:dp_translate_f: input is 0899000000
Dec 22 23:39:26 [892] DBG:dialplan:dp_translate_f: Checking with dpid 10
Dec 22 23:39:26 [892] DBG:dialplan:translate: No matching rule for input 0899000000
Dec 22 23:39:26 [892] DBG:dialplan:dp_translate_f: could not translate 0899000000 with dpid 10
Dec 22 23:39:26 [892] DBG:dialplan:dp_translate_f: dpid is 10 partition is default
Dec 22 23:39:26 [892] DBG:dialplan:dp_get_svalue: searching 15
Dec 22 23:39:26 [892] DBG:dialplan:dp_translate_f: input is 0899000000
Dec 22 23:39:26 [892] DBG:dialplan:dp_translate_f: Checking with dpid 10
Dec 22 23:39:26 [892] DBG:dialplan:translate: No matching rule for input 0899000000
Dec 22 23:39:26 [892] DBG:dialplan:dp_translate_f: could not translate 0899000000 with dpid 10
Dec 22 23:39:26 [892] DBG:registrar:parse_lookup_flags: final flags: 1
Dec 22 23:39:26 [892] DBG:registrar:lookup: '0899631338@example.ie' Not found in usrloc

Dialplan rule I am using is

MariaDB [opensips]> select * from dialplan;
+----+------+----+----------+----------------+-------------+-------------+-----------+---------+----------+----------------+
| id | dpid | pr | match_op | match_exp      | match_flags | subst_exp   | repl_exp  | timerec | disabled | attrs          |
+----+------+----+----------+----------------+-------------+-------------+-----------+---------+----------+----------------+
|  2 |   10 |  1 |        0 | ^089[0-9]{7}+$ |           0 | "^089(.+)$" | "35389\1" | NULL    |        0 | IE Lyca Mobile |
+----+------+----+----------+----------------+-------------+-------------+-----------+---------+----------+----------------+

my gateway list

MariaDB [opensips]> select * from dr_gateways;
+----+------+------+-----------------+-------+------------+-------+------------+-------+--------+-------------+
| id | gwid | type | address         | strip | pri_prefix | attrs | probe_mode | state | socket | description |
+----+------+------+-----------------+-------+------------+-------+------------+-------+--------+-------------+
|  1 | 1    |    1 | 1.1.1.1         |     0 |            |       |          0 |     0 |        | inbound     |
|  2 | 2    |    2 | 2.2.2.2         |     0 |            |       |          0 |     1 |        | gw 1        |
|  3 | 3    |    2 | 3.3.3.3         |     0 |            |       |          0 |     0 |        | gw 2        |
|  4 | 4    |    2 | 4.4.4.4         |     0 |            |       |          0 |     0 |        | gw 3        |
|  5 | 5    |    2 | 5.5.5.5         |     0 |            |       |          0 |     0 |        | gw 4        |
+----+------+------+-----------------+-------+------------+-------+------------+-------+--------+-------------+

Carriers

MariaDB [opensips]> select * from dr_carriers;
+----+-----------+---------+-------+-------+-------+-------------+
| id | carrierid | gwlist  | flags | state | attrs | description |
+----+-----------+---------+-------+-------+-------+-------------+
|  1 |           | 2,3,4,5 |     0 |     0 |       | Provide     |
+----+-----------+---------+-------+-------+-------+-------------+

DR Rules

MariaDB [opensips]> select * from dr_rules;
+--------+---------+--------+---------+----------+---------+---------+-------+-------------+
| ruleid | groupid | prefix | timerec | priority | routeid | gwlist  | attrs | description |
+--------+---------+--------+---------+----------+---------+---------+-------+-------------+
|      1 | 0,1     | 353    |         |        1 |         | 2,3,4,5 |       | IE          |
+--------+---------+--------+---------+----------+---------+---------+-------+-------------+
1 row in set (0.001 sec)

my opensips.cfg file

 #
# 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
# for a explanation of possible statements, functions and parameters.
#


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

log_level=3
log_stderror=no
log_facility=LOG_LOCAL0

children=4

/* uncomment the following lines to enable debugging */
debug_mode=yes

/* uncomment the next line to enable the auto temporary blacklisting of
   not available destinations (default disabled) */
#disable_dns_blacklist=no

/* uncomment the next line to enable IPv6 lookup after IPv4 dns
   lookup failures (default disabled) */
#dns_try_ipv6=yes

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


listen=udp:123.123.123.123:5060   # CUSTOMIZE ME
listen=tcp:123.123.123.123:5060   # CUSTOMIZE ME


####### 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"
/* 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)

#### URI module
loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)

#### MYSQL module
loadmodule "db_mysql.so"

#### HTTPD module
loadmodule "httpd.so"
modparam("httpd", "port", 8888)

#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "db_mode",   2)
modparam("usrloc", "db_url",
        "mysql://opensips:secret@localhost/opensips") # CUSTOMIZE ME


#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
modparam("registrar", "received_avp", "$avp(received_nh)")/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)

#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
   if you enable this parameter, be sure the enable "append_fromtag"
   in "rr" module */
modparam("acc", "detect_direction", 0)
modparam("acc", "db_url",
        "mysql://opensips:secret@localhost/opensips") # CUSTOMIZE ME

#### AUTHentication modules
loadmodule "auth.so"
loadmodule "auth_db.so"
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("auth_db|uri", "db_url",
        "mysql://opensips:secret@localhost/opensips") # CUSTOMIZE ME
modparam("auth_db", "load_credentials", "")

#### ALIAS module
loadmodule "alias_db.so"
modparam("alias_db", "db_url",
        "mysql://opensips:secret@localhost/opensips") # CUSTOMIZE ME

#### DOMAIN module
loadmodule "domain.so"
modparam("domain", "db_url",
        "mysql://opensips:secret@localhost/opensips") # CUSTOMIZE ME
modparam("domain", "db_mode", 1)   # Use caching
modparam("auth_db|usrloc|uri", "use_domain", 1)

#### PRESENCE modules
loadmodule "xcap.so"
loadmodule "presence.so"
loadmodule "presence_xml.so"
modparam("xcap|presence", "db_url",
        "mysql://opensips:secret@localhost/opensips") # CUSTOMIZE ME
modparam("presence_xml", "force_active", 1)
modparam("presence", "fallback2db", 0)

#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 21600)  # 6 hours timeout
modparam("dialog", "db_mode", 2)
modparam("dialog", "db_url",
        "mysql://opensips:secret@localhost/opensips") # CUSTOMIZE ME

####  NAT modules
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 10)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", "SIP_PING_FLAG")
modparam("nathelper", "sipping_from", "sip:pinger@127.0.0.1") #CUSTOMIZE ME
modparam("nathelper", "received_avp", "$avp(received_nh)")

loadmodule "rtpengine.so"
modparam("rtpengine", "rtpengine_sock", "udp:localhost:2223") # CUSTOMIZE ME

####  DIALPLAN module
loadmodule "dialplan.so"
modparam("dialplan", "db_url",
        "mysql://opensips:secret@localhost/opensips") # CUSTOMIZE ME

####  DYNAMMIC ROUTING module
loadmodule "drouting.so"
modparam("drouting", "db_url",
        "mysql://opensips:secret@localhost/opensips") # CUSTOMIZE ME

####  MI_HTTP module
loadmodule "mi_http.so"
loadmodule "mi_json.so"
loadmodule "proto_udp.so"
loadmodule "proto_tcp.so"
####### Routing Logic ########

# main request routing logic

route{

        # initial NAT handling; detect if the request comes from behind a NAT
        # and apply contact fixing
        force_rport();
        if (nat_uac_test("23")) {
                if (is_method("REGISTER")) {
                        fix_nated_register();
                        setbflag(NAT);
                } else {
                        fix_nated_contact();
                        setflag(NAT);
                }
        }

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

        if (has_totag()) {

                # 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() ) {
                        if (is_method("SUBSCRIBE") && is_myself("$rd")) {
                                # in-dialog subscribe requests
                                route(handle_presence);
                                exit;
                        }
                        # 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;
                }

                # validate the sequential request against dialog
                if ( $DLG_status!=NULL && !validate_dialog() ) {
                        xlog("In-Dialog $rm from $si (callid=$ci) is not valid according to dialog\n");
                        ## exit;
                }

                if (is_method("BYE")) {
                        # do accounting even if the transaction fails
                        do_accounting("db","failed");

                }


                if (check_route_param("nat=yes"))
                        setflag(NAT);
                # 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 (t_check_trans())
                        t_relay();
                exit;
        }

        # absorb retransmissions, but do not create transaction
        t_check_trans();

        if ( !(is_method("REGISTER")  || is_from_gw() ) ) {

                if (is_from_local()) {
                        # authenticate if from local subscriber
                        # authenticate all initial non-REGISTER request that pretend to be
                        # generated by local subscriber (domain from FROM URI is local)
                        if (!proxy_authorize("", "subscriber")) {
                                proxy_challenge("", "0");
                                exit;
                        }
                        if (!db_check_from()) {
                                send_reply("403","Forbidden auth ID");
                                exit;
                        }

                        consume_credentials();
                        # caller authenticated

                } else {
                        # if caller is not local, then called number must be local

                        if (!is_uri_host_local()) {
                                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"))
                        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;
                }

                do_accounting("db");

        }


        if (!is_uri_host_local()) {
                append_hf("P-hint: outbound\r\n");

                route(relay);
        }

        # requests for my domain

        if( is_method("PUBLISH|SUBSCRIBE"))
                        route(handle_presence);

        if (is_method("REGISTER")) {
                # authenticate the REGISTER requests
                if (!www_authorize("", "subscriber")) {
                        www_challenge("", "0");
                        exit;
                }

                if (!db_check_to()) {
                        send_reply("403","Forbidden auth ID");
                        exit;
                }
                if ($proto == "tcp")
                        setflag(TCP_PERSISTENT);
                if (isflagset(NAT)) {
                        setbflag(SIP_PING_FLAG);
                }
                if (!save("location"))
                        sl_reply_error();

                exit;
        }

        if ($rU==NULL) {
                # request with no Username in RURI
                send_reply("484","Address Incomplete");
                exit;
        }


        # apply DB based aliases
        alias_db_lookup("dbaliases");


        **# apply transformations from dialplan table
        dp_translate("10","$rU/$rU");


        if (dp_translate("10","$rU/$rU") ) {

                if (!do_routing("0")) {
                        send_reply("500","No PSTN Route found");
                        exit;
                }

                route(relay);
                exit;
        }**


        # do lookup with method filtering
        if (!lookup("location","m")) {
                if (!db_does_uri_exist()) {
                        send_reply("420","Bad Extension");
                        exit;
                }

                # redirect to a different VM system
                $du = "sip:127.0.0.2:5060"; # CUSTOMIZE ME
                route(relay);

        }

        if (isbflagset(NAT)) setflag(NAT);

        # when routing via usrloc, log the missed calls also
        do_accounting("db","missed");

        route(relay);
}


route[relay] {
        # for INVITEs enable some additional helper routes
        if (is_method("INVITE")) {

                if (isflagset(NAT)) {
                        rtpengine_offer("ro");
                }

                t_on_branch("per_branch_ops");
                t_on_reply("handle_nat");
                t_on_failure("missed_call");
        }

        if (isflagset(NAT)) {
                add_rr_param(";nat=yes");
        }

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


# Presence route
route[handle_presence]
{
        if (!t_newtran()) {
                sl_reply_error();
                exit;
        }

        if(is_method("PUBLISH")) {
                handle_publish();
        } else
        if( is_method("SUBSCRIBE")) {
                handle_subscribe();
        }

        exit;
}


branch_route[per_branch_ops] {
        xlog("new branch at $ru\n");
}


onreply_route[handle_nat] {
        if (nat_uac_test("1"))
                fix_nated_contact();
        if ( isflagset(NAT) )
                rtpengine_answer("ro");
        xlog("incoming reply\n");
}


failure_route[missed_call] {
        if (t_was_cancelled()) {
                exit;
        }

        # uncomment the following lines if you want to block client
        # redirect based on 3xx replies.
        ##if (t_check_status("3[0-9][0-9]")) {
        ##t_reply("404","Not found");
        ##      exit;
        ##}


        # redirect the failed to a different VM system
        if (t_check_status("486|408")) {
                $du = "sip:127.0.0.2:5060"; # CUSTOMIZE ME
                # do not set the missed call flag again
                route(relay);
        }
}



local_route {
        if (is_method("BYE") && $DLG_dir=="UPSTREAM") {

                acc_db_request("200 Dialog Timeout", "acc");

        }
}

1 Answers1

0

In the dialplan table, you have added extra quotes around the dialplan.subst_exp and dialplan.repl_exp values. Instead of "^089(.+)$" and "35389\1", try to provision ^089(.+)$ and 35389\1. Another mistake is that you are using match_op == 0 (string match) instead of match_op == 1 (regex match). Please read the dialplan documentation carefully before provisioning data into any of the columns.

The drouting part looks good. It should properly route out the 353 prefix.

Liviu Chircu
  • 1,000
  • 3
  • 11
  • 24
  • I have done that, but still getting the same behaviour. – Kristaps Dravnieks Dec 23 '19 at 10:00
  • In terminal I am getting "No matching rule for input 0899000000" even I believe regex is correct. – Kristaps Dravnieks Dec 23 '19 at 10:01
  • https://topaz.github.io/paste/#XQAAAQAmAwAAAAAAAAA2nkquIdRDg4Y3FZKAE0RXPFOW6h01f0n6FYUT6opS8Mk0dYK1+u4tJgooYKG5M4DOPlwF9UcNHY5yl5xC3qtHqmZWYJvZFe6BEmlmYtVQgps8D85IL+ldeEWVe0N/BHglj2xgy/cbSEZ5KvKHQmBYEeDy752X993KhSMT/dw72aTUx9wdk6antYwFYWLeZhA/V4i2EIVSuobMZscdTM0BCqb6NC8D6/LwMQGArj4oYhTB94J6XA6HWLou+TZcqnvtK/9jYD5/nmqg7vDeXIsZuL68cy7sDLLC9Vjio+tMb3OsJVsAlfuD4wwruIeBDoJhVPzHzckTbIxb4O/U89b7vjzpFihYKUwd9kNNuADrYwO/wKeFzKqv+rkBsdBX14PEYJJXU8+hcYMI8HbHbLqDYZHT2c+xf5XlZIKxNW7i+K7i7a5C6KoFpEscZhZxU2up8Bomkkv8Sf/y – Liviu Chircu Dec 23 '19 at 11:06
  • Ok, now I understand. It looks like you are using `match_op = 0`, which is string matching, as opposed to `match_op = 1`, which is regex matching! – Liviu Chircu Dec 23 '19 at 11:07
  • Thank You! Got one step further, opensipscp has to be corrected, when adding dialplan rule from cp 0 is for regeq and 1 is for equal. – Kristaps Dravnieks Dec 23 '19 at 11:39
  • I can see, now call hits dp_translate rule, gets converted to E164 but I don't see any route lookup after checking userloc – Kristaps Dravnieks Dec 23 '19 at 11:50
  • On sngrep I see response to invite "SIP/2.0 420 Bad Extension" – Kristaps Dravnieks Dec 23 '19 at 12:00
  • do `"opensipsctl ul show"` and make sure that exact DID is registered, otherwise the `lookup(DID)` operation will fail! – Liviu Chircu Dec 23 '19 at 21:02