qrouting (Quality-based Routing) Module
     __________________________________________________________

   Table of Contents

   1. Admin Guide

        1.1. Overview
        1.2. Monitored Statistics
        1.3. Dependencies

              1.3.1. OpenSIPS Modules

        1.4. Exported Parameters

              1.4.1. db_url (string)
              1.4.2. table_name (string)
              1.4.3. algorithm (integer)
              1.4.4. history_span (integer)
              1.4.5. sampling_interval (integer)
              1.4.6. extra_stats (string)
              1.4.7. min_samples_asr (integer)
              1.4.8. min_samples_ccr (integer)
              1.4.9. min_samples_pdd (integer)
              1.4.10. min_samples_ast (integer)
              1.4.11. min_samples_acd (integer)
              1.4.12. event_bad_dst_threshold (string)
              1.4.13. decimal_digits (string)

        1.5. Exported Functions

              1.5.1. qr_set_xstat(rule_id, gw_name, stat_name,
                      inc_by, [part], [inc_total])

              1.5.2. qr_disable_dst(rule_id, dst_name, [part])
              1.5.3. qr_enable_dst(rule_id, dst_name, [part])

        1.6. Exported MI Functions

              1.6.1. qr_reload
              1.6.2. qr_status
              1.6.3. qr_disable_dst
              1.6.4. qr_enable_dst

        1.7. Exported Events

              1.7.1. E_QROUTING_BAD_DST

   2. Contributors

        2.1. By Commit Statistics
        2.2. By Commit Activity

   3. Documentation

        3.1. Contributors

   List of Tables

   2.1. Top contributors by DevScore^(1), authored commits^(2) and
          lines added/removed^(3)

   2.2. Most recently active contributors^(1) to this module

   List of Examples

   1.1. Setting the db_url parameter
   1.2. Setting the table_name parameter
   1.3. Setting the algorithm parameter
   1.4. Setting the connection_timeout parameter
   1.5. Setting the connect_poll_interval parameter
   1.6. Setting the extra_stats parameter
   1.7. Setting the min_samples_asr parameter
   1.8. Setting the min_samples_ccr parameter
   1.9. Setting the min_samples_pdd parameter
   1.10. Setting the min_samples_ast parameter
   1.11. Setting the min_samples_acd parameter
   1.12. Setting the event_bad_dst_threshold parameter
   1.13. Setting the decimal_digits parameter
   1.14. qr_set_xstat() usage
   1.15. qr_disable_dst() usage
   1.16. qr_enable_dst() usage

Chapter 1. Admin Guide

1.1. Overview

   qrouting is a module which sits on top of drouting, dialog and
   tm and performs live tracking of a series of essential gateway
   signaling quality indicators (i.e. ASR, CCR, PDD, AST, ACD --
   more details below). Thus, qrouting is able to adjust the
   prefix routing behavior at runtime, by dynamically re-ordering
   the gateways based on how well they perform during live
   traffic, such that:
     * well-performing gateways get prioritized for routing
     * gateways which show a degradation in signaling quality are
       demoted to the end of the routing list

1.2. Monitored Statistics

   The module keeps track of a series of statistics, for each
   drouting (prefix, destination) pair, where a "destination" may
   be either a gateway or a carrier. The statistics are:
     * ASR (Answer Seizure Ratio) - the percentage of telephone
       calls which are answered (200 reply status code).
     * CCR (Call Completion Ratio) - the percentage of telephone
       calls which are answered back by the gateway, excluding
       5xx, 6xx reply codes and internal 408 timeouts. The
       following is always true: CCR >= ASR.
     * PDD (Post Dial Delay) - the duration, in milliseconds,
       between the receival of the initial INVITE and the receival
       of the first 180/183 provisional reply (the call state
       advances to "ringing").
     * AST (Average Setup Time) - the duration, in milliseconds,
       between the receival of the initial INVITE and the receival
       of the first 200 OK reply (the call state advances to
       "answered"). The following is always true: AST >= PDD.
     * ACD (Average Call Duration) - the duration, in seconds,
       between the receival of the initial INVITE and the receival
       of the first BYE request from either participant (the call
       state advances to "ended").

1.3. Dependencies

1.3.1. OpenSIPS Modules

   The following modules must be loaded for this module to work:
     * an SQL DB module, offering access to the "qr_profiles"
       table
     * tm
     * dialog
     * drouting

1.4. Exported Parameters

1.4.1. db_url (string)

   An SQL database URL.

   Default value is NULL.

   Example 1.1. Setting the db_url parameter

modparam("qrouting", "db_url", "mysql://opensips:opensipsrw@localhost/op
ensips")

1.4.2. table_name (string)

   The name of the quality-based routing profiles table.

   Default value is "qr_profiles".

   Example 1.2. Setting the table_name parameter

modparam("qrouting", "table_name", "qr_profiles_bak")

1.4.3. algorithm (integer)

   Quality-based destination selection/balancing algorithm to use.

   Possible values:
     * "dynamic-weights" - for each prefix, all destinations start
       with equal weights and receive an equal share of the
       traffic. As signaling statistics are gathered for the
       destinations, the ones which underperform will receive less
       traffic, based on the "penalty" columns of the qr_profiles
       table
     * "best-dest-first" - for each prefix, the 1st (i.e. best
       scoring) destination will receive all the traffic as long
       as its quality stays the same. Initially, all destinations
       start with a perfect score. This score may degrade if one
       or more signaling statistics fall below the "warn" or
       "crit" thresholds during routing, case in which the
       destinations will be sorted accordingly and traffic will be
       routed to the newly determined 1st position in the list
       NOTE: for optimal results when using the "best-dest-first"
       algorithm, the destinations must be provisioned in
       descending order of their expected quality! (i.e. best
       quality gateways must be placed towards the start of the
       list)

   Default value is "dynamic-weights".

   Example 1.3. Setting the algorithm parameter

modparam("qrouting", "algorithm", "best-dest-first")

1.4.4. history_span (integer)

   The duration (in minutes) that a gateway's statistics for a
   given call will be kept for.

   Default value is 30 minutes.

   Example 1.4. Setting the connection_timeout parameter

modparam("qrouting", "history_span", 15)

1.4.5. sampling_interval (integer)

   The duration (in seconds) of the statistics sampling window.
   Every sampling_interval seconds, the accumulated statistics
   during the most recent sampling window get added to each
   gateway, while the oldest sampled interval statistics are
   subtracted (rotated away) from each gateway.

   A lower value will lead to a closer to realtime adjustment to
   traffic changes, but it will also increase CPU usage and
   internal contention due to locking.

   Default value is 5 seconds.

   Example 1.5. Setting the connect_poll_interval parameter

modparam("qrouting", "sampling_interval", 5)

1.4.6. extra_stats (string)

   A semicolon-separated list of custom statistics to be
   additionally kept and monitored by the module. In order to
   gather these statistics, the module expects the script writer
   to call qr_set_xstat() whenever they want to increment a custom
   statistic for a (prefix, destination) tuple.

   Extra statistics come in two flavours: positive (a higher value
   is better, e.g. ASR) or negative (a lower value is better, e.g.
   PDD). The flavour determines the comparison operator to be used
   against the statistics's thresholds, and can be specified by
   prepending "+" or "-", respectively, in front of the
   statistic's name (see example below).

   The minimally accepted number of samples for each statistic may
   be changed using the optional /<min_samples> suffix. Default
   value: 30 samples (minimum).

   The thresholds and penalties for a custom statistic must be
   provided via the qr_profiles table, by extending it with 4
   columns for each extra statistic, named according to these
   templates:
     * warn_threshold_<STAT>
     * crit_threshold_<STAT>
     * warn_penalty_<STAT>
     * crit_penalty_<STAT>

   Default value is NULL.

   Example 1.6. Setting the extra_stats parameter

modparam("qrouting", "extra_stats", "+mos/60; +r_factor; -503_replies/10
0")

1.4.7. min_samples_asr (integer)

   The minimally accepted amount of sampled ASR statistics for
   each (prefix, destination) pair before they can be taken into
   account. As long as the number of samples stays below this
   limit, the ASR statistic of the pair is assumed to be healthy.

   Default value is 30.

   Example 1.7. Setting the min_samples_asr parameter

modparam("qrouting", "min_samples_asr", 50)

1.4.8. min_samples_ccr (integer)

   The minimally accepted amount of sampled CCR statistics for
   each (prefix, destination) pair before they can be taken into
   account. As long as the number of samples stays below this
   limit, the CCR statistic of the pair is assumed to be healthy.

   Default value is 30.

   Example 1.8. Setting the min_samples_ccr parameter

modparam("qrouting", "min_samples_ccr", 50)

1.4.9. min_samples_pdd (integer)

   The minimally accepted amount of sampled PDD statistics for
   each (prefix, destination) pair before they can be taken into
   account. As long as the number of samples stays below this
   limit, the PDD statistic of the pair is assumed to be healthy.

   Default value is 10.

   Example 1.9. Setting the min_samples_pdd parameter

modparam("qrouting", "min_samples_pdd", 15)

1.4.10. min_samples_ast (integer)

   The minimally accepted amount of sampled AST statistics for
   each (prefix, destination) pair before they can be taken into
   account. As long as the number of samples stays below this
   limit, the AST statistic of the pair is assumed to be healthy.

   Default value is 10.

   Example 1.10. Setting the min_samples_ast parameter

modparam("qrouting", "min_samples_ast", 15)

1.4.11. min_samples_acd (integer)

   The minimally accepted amount of sampled ACD statistics for
   each (prefix, destination) pair before they can be taken into
   account. As long as the number of samples stays below this
   limit, the ACD statistic of the pair is assumed to be healthy.

   Default value is 20.

   Example 1.11. Setting the min_samples_acd parameter

modparam("qrouting", "min_samples_acd", 30)

1.4.12. event_bad_dst_threshold (string)

   The minimally accepted quality of a (prefix, destination)
   combination, given as a quoted floating point number in the [0,
   1] interval. Whenever a (prefix, destination) combination
   receives a score below this threshold, the E_QROUTING_BAD_DST
   event will be triggered.

   Default value is NULL (not set).

   Example 1.12. Setting the event_bad_dst_threshold parameter

modparam("qrouting", "event_bad_dst_threshold", "0.5")

1.4.13. decimal_digits (string)

   The amount of decimal digits to use in logging or MI output.

   Default value is 2.

   Example 1.13. Setting the decimal_digits parameter

modparam("qrouting", "decimal_digits", 4)

1.5. Exported Functions

1.5.1.  qr_set_xstat(rule_id, gw_name, stat_name, inc_by, [part],
[inc_total])

   Provide a new sample value for an extra statistic on a given
   (prefix, gateway) combination. Extra statistics may be defined
   using the extra_stats module parameter.

   Parameters:
     * rule_id (integer) - database id of the drouting rule
       holding the prefix and its destinations
     * gw_name (string) - gateway to account the statistic for.
       The gateway must be part of the above rule's destinations.
     * stat_name (string) - statistic to account
     * inc_by (string) - quoted floating point number,
       representing the amount to add to the stat
     * part (string, optional, default: 'Default') - the drouting
       partition to use
     * inc_total (string, optional, default: 1) - the amount to
       add to the total stat counter. Usually, this value should
       be 1, but it may make sense to set it to 0 when a custom
       statistic needs to be set a 2nd, 3rd, etc. time across the
       duration of the same established call.

   This function can be used from any route.

   Example 1.14. qr_set_xstat() usage

# the MoS is set exactly once per call, so we can omit "inc_total"
$var(rule_id) = 1574;
$var(gw_name) = "GW-28";
$var(mos_score) = "4.28";
qr_set_xstat($var(rule_id), $var(gw_name), "mos", $var(mos_score));

1.5.2.  qr_disable_dst(rule_id, dst_name, [part])

   Within a given routing rule, temporarily remove the given
   gateway or carrier from routing, until they are re-enabled via
   qr_enable_dst() or qr_enable_dst. The removal effect will be
   lost on an OpenSIPS restart.

   Parameters:
     * rule_id (integer) - database id of the drouting rule
     * dst_name (string) - gateway or carrier to disable
     * part (string, optional) - drouting partition

   This function can be used from any route.

   Example 1.15. qr_disable_dst() usage

# the signaling quality for @rule_id through @dst_name is degrading, rem
ove it!
event_route [E_QROUTING_BAD_DST]
{
        qr_disable_dst($param(rule_id), $param(dst_name), $param(partiti
on));
}

1.5.3.  qr_enable_dst(rule_id, dst_name, [part])

   Within a given routing rule, re-introduce the given gateway or
   carrier into the routing process.

   Parameters:
     * rule_id (integer) - database id of the drouting rule
     * dst_name (string) - gateway or carrier to disable
     * part (string, optional) - drouting partition

   This function can be used from any route.

   Example 1.16. qr_enable_dst() usage

# the ban has expired, let's re-enable this gateway and see how it behav
es
qr_enable_dst($param(rule_id), $param(dst_name), $param(partition));

1.6. Exported MI Functions

1.6.1. qr_reload

   Reload all quality-based routing rules from the SQL database.

   MI FIFO Command Format:

opensips-cli -x mi qr_reload

1.6.2. qr_status

   Inspect the signaling quality statistics of the current
   history_span for all drouting gateways in all partitions, with
   various levels of filtering.

   Parameters:
     * partition (optional) - a specific drouting partition to
       list statistics for
     * rule_id (optional) - a specific drouting rule database id
       to list statistics for
     * dst_name (optional) - a specific gateway or carrier name to
       list statistics for

   MI FIFO Command Format:

opensips-cli -x mi qr_status
opensips-cli -x mi qr_status pstn
opensips-cli -x mi qr_status pstn 11 MY-GW-3
opensips-cli -x mi qr_status pstn 17 MY-CARR-7

1.6.3. qr_disable_dst

   Within a given routing rule, temporarily remove the given
   gateway or carrier from routing, until they are re-enabled
   manually. The removal effect will be lost on an OpenSIPS
   restart.

   Parameters:
     * partition (optional) - drouting partition
     * rule_id - database id of the drouting rule
     * dst_name - gateway or carrier to disable

   MI FIFO Command Format:

opensips-cli -x mi qr_disable_dst 14 MY-CARR-7
opensips-cli -x mi qr_disable_dst pstn 81 MY-GW-3

1.6.4. qr_enable_dst

   Within a given routing rule, re-introduce the given gateway or
   carrier into the routing process.

   Parameters:
     * partition (optional) - drouting partition
     * rule_id - database id of the drouting rule
     * dst_name - gateway or carrier to enable

   MI FIFO Command Format:

opensips-cli -x mi qr_enable_dst 14 MY-CARR-7
opensips-cli -x mi qr_enable_dst pstn 81 MY-GW-3

1.7. Exported Events

1.7.1.  E_QROUTING_BAD_DST

   This event may be raised during routing, asynchronously,
   whenever the score of a (prefix, destination) pair falls below
   event_bad_dst_threshold.

   Parameters:
     * partition - drouting partition name
     * rule_id - database id of the drouting rule
     * dst_name - name of the concerned gateway or carrier

Chapter 2. Contributors

2.1. By Commit Statistics

   Table 2.1. Top contributors by DevScore^(1), authored
   commits^(2) and lines added/removed^(3)
     Name DevScore Commits Lines ++ Lines --
   1. Liviu Chircu (@liviuchircu) 152 65 4818 2748
   2. Mihai Tiganus (@tallicamike) 49 15 2955 509
   3. Maksym Sobolyev (@sobomax) 6 4 6 7
   4. Zero King (@l2dy) 3 1 1 1
   5. Bogdan-Andrei Iancu (@bogdan-iancu) 2 1 0 3
   6. Razvan Crainea (@razvancrainea) 2 1 0 2

   (1) DevScore = author_commits + author_lines_added /
   (project_lines_added / project_commits) + author_lines_deleted
   / (project_lines_deleted / project_commits)

   (2) including any documentation-related commits, excluding
   merge commits. Regarding imported patches/code, we do our best
   to count the work on behalf of the proper owner, as per the
   "fix_authors" and "mod_renames" arrays in
   opensips/doc/build-contrib.sh. If you identify any
   patches/commits which do not get properly attributed to you,
   please submit a pull request which extends "fix_authors" and/or
   "mod_renames".

   (3) ignoring whitespace edits, renamed files and auto-generated
   files

2.2. By Commit Activity

   Table 2.2. Most recently active contributors^(1) to this module
                     Name                   Commit Activity
   1. Maksym Sobolyev (@sobomax)          Oct 2020 - Feb 2023
   2. Liviu Chircu (@liviuchircu)         Jan 2020 - Apr 2021
   3. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2020 - Mar 2020
   4. Zero King (@l2dy)                   Mar 2020 - Mar 2020
   5. Razvan Crainea (@razvancrainea)     Feb 2020 - Feb 2020
   6. Mihai Tiganus (@tallicamike)        Aug 2014 - Nov 2014

   (1) including any documentation-related commits, excluding
   merge commits

Chapter 3. Documentation

3.1. Contributors

   Last edited by: Liviu Chircu (@liviuchircu).

   Documentation Copyrights:

   Copyright © 2020 www.opensips-solutions.com
