CGRateS Module


Table of Contents

1. Admin Guide
1.1. Overview
1.2. Authorization
1.3. Accounting
1.4. Other Commands
1.5. CGRateS Failover
1.6. Dependencies
1.6.1. OpenSIPS Modules
1.6.2. External Libraries or Applications
1.7. Exported Parameters
1.7.1. cgrates_engine (string)
1.7.2. bind_ip (string)
1.7.3. max_async_connections (integer)
1.7.4. retry_timeout (integer)
1.8. Exported Functions
1.8.1. cgrates_acc([flags[, account[, destination[, session]]]])
1.8.2. cgrates_auth([account[, destination[, session]]])
1.8.3. cgrates_cmd(command[, session])
1.9. Exported pseudo-variables
1.9.1. $cgr(name) / $(cgr(name)[session])
1.9.2. $cgrret
1.10. Exported Asynchronous Functions
1.10.1. cgrates_auth([account[, destination[, session]]])
1.10.2. cgrates_cmd(command[, session])
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. Set cgrates_engine parameter
1.2. Set bind_ip parameter
1.3. Set max_async_connections parameter
1.4. Set retry_timeout parameter
1.5. cgrates_acc() usage
1.6. cgrates_auth() usage
1.7. cgrates_cmd() usage
1.8. $cgr(name) simple usage
1.9. $cgr(name) multiple sessions usage
1.10. $cgrret usage
1.11. async cgrates_auth usage
1.12. async cgrates_cmd usage

Chapter 1. Admin Guide

1.1. Overview

CGRateS is an open-source rating engine used for carrier-grade, multi-tenant, real-time billing. It is able to do both postpaid and prepaid rating for multiple concurrent sessions with different balance units (eg: Monetary, SMS, Internet Traffic). CGRateS can also export accurate CDRs in various formats.

This module can be used to communicate with the CGRates engine in order to do call authorization and accounting for billing purposes. The OpenSIPS module does not do any billing by itself, but provides an interface to communicate with the CGRateS engine using efficient JSON-RPC APIs in both synchronous and asynchronous ways. For each command the user can provide a set of parameters that will be forwarded to the CGRateS engine, using the $cgr() variable. You can find usage examples in the following sections.

The module also has support for multiple parallel billing sessions to CGRateS. This can be useful in scenarios that involve complex billing logic, such as double billing (both customer and carrier billing), or multi-leg calls (serial/parallel forking). Each billing session is independent and has a specific tag that can be use throughout the call lifetime.

The module can be used to implement the following features:

1.2. Authorization

The authorization is used to check if an account is allowed to start a new call and it has enough credit to call to that destination. This is done using the cgrates_auth() command, which returns the number of seconds a call is allowed to run in the $cgrret pseudo-variable.

Usage example:

		...
		if (cgrates_auth("$fU", "$rU"))
			xlog("Call is allowed to run $cgrret seconds\n");
		}
		...
		

1.3. Accounting

The accounting mode is used to start and stop a CGRateS session. This can be used for both prepaid and postpaid billing. The cgrates_acc() function starts the CGRateS session when the call is answered (the 200 OK message is received) and ends it when the call is ended (a BYE message is received). This is done automatically using the dialog module.

Note that it is important to first authorize the call (using the cgrates_auth() command) before starting accounting. If you do not do this and the user is not authorized to call, the dialog will be immediately closed, resulting in a 0-duration call. If the call is allowed to go on, the dialog lifetime will be set to the duration indicated by the CGRateS engine. Therefore, the dialog will be automatically ended if the call would have been longer.

After the call is ended (by a BYE message), the CGRateS session is also ended. At this point, you can generate a CDR. To do this, you have to set the cdr flag to the cgrates_acc() command. CDRs can also be generated for missed calls by using the missed flag.

Usage example:

		...
		if (!cgrates_auth("$fU", "$rU")) {
			sl_send_reply("403", "Forbidden");
			exit;
		}
		xlog("Call is allowed to run $cgrret seconds\n");
		# do accounting for this call
		cgrates_acc("cdr", "$fU", "$rU");
		...
		

Note that when using the cdr flag, CDRs are exported by the CGRateS engine in various formats, not by OpenSIPS. Check the CGRateS documentation for more information.

1.4. Other Commands

You can use the cgrates_cmd() to send arbitrary commands to the CGRateS engine, and use the $cgrret pseudo-variable to retrieve the response.

The following example simulates the cgrates_auth() CGRateS call:

		...
		$cgr(Tenant) = $fd;
		$cgr(Account) = $fU;
		$cgr(OriginID) = $ci;
		$cgr(SetupTime) = "" + $Ts;
		$cgr(RequestType) = "*prepaid";
		$cgr(Destination) = $rU;
		cgrates_cmd("SMGenericV1.GetMaxUsage");
		xlog("Call is allowed to run $cgrret seconds\n");
		...
		

1.5. CGRateS Failover

Multiple CGRateS engines can be provisioned to use in a failover manner: in case one engine is down, the next one is used. Currently there is no load balancing logic between the servers, but this is a feature one of the CGRateS component does starting with newer versions.

Each CGRateS engine has assigned up to max_async_connections connections, plus one used for synchronous commands. If a connection fails (due to network issues, or server issues), it is marked as closed and a new one is tried. If all connections to that engine are down, then the entire engine is marked as disabled, and a new engine is queried. After an engine is down for more than retry_timeout seconds, OpenSIPS tries to connect once again to that server. If it succeeds, that server is enabled. Otherwise, the other engines are used, until none is available and the command fails.

1.6. Dependencies

1.6.1. OpenSIPS Modules

The following modules must be loaded before this module:

  • dialog -- in case CGRateS accounting is used.

1.6.2. External Libraries or Applications

The following libraries or applications must be installed before running OpenSIPS with this module loaded:

  • libjson

1.7. Exported Parameters

1.7.1. cgrates_engine (string)

This parameter is used to specify a CGRateS engine connection. The format is IP[:port]. The port is optional, and if missing, 2014 is used.

This parameter can have multiple values, for each server used for failover. At least one server should be provisioned.

Default value is None.

Example 1.1. Set cgrates_engine parameter

...
modparam("cgrates", "cgrates_engine", "127.0.0.1")
modparam("cgrates", "cgrates_engine", "127.0.0.1:2013")
...

1.7.2. bind_ip (string)

IP used to bind the socket that communicates with the CGRateS engines. This is useful to set when the engine is runing in a local, secure LAN, and you want to use that network to communicate with your servers. The parameter is optional.

Default value is not set - any IP is used.

Example 1.2. Set bind_ip parameter

...
modparam("cgrates", "bind_ip", "10.0.0.100")
...

1.7.3. max_async_connections (integer)

The maximum number of simultaneous asynchronous connections to a CGRateS engine.

Default value is 10.

Example 1.3. Set max_async_connections parameter

...
modparam("cgrates", "max_async_connections", 20)
...

1.7.4. retry_timeout (integer)

The number of seconds after which a disabled connection/engine is retried.

Default value is 60.

Example 1.4. Set retry_timeout parameter

...
modparam("cgrates", "retry_timeout", 120)
...

1.8. Exported Functions

1.8.1.  cgrates_acc([flags[, account[, destination[, session]]]])

cgrates_acc() starts an accounting session on the CGRateS engine for the current dialog. It also ends the session when the dialog is ended. This function requires a dialog, so in case create_dialog() was not previously used, it will internally call that function.

Note that the cgrates_acc() function does not send any message to the CGRateS engine when it is called, but only when the call is answered and the CGRateS session should be started (a 200 OK message is received).

When called in REQUEST_ROUTE or FAILURE_ROUTE, accounting for this session is done for all the branches created. When called in BRANCH_ROUTE or ONREPLY_ROUTE, acccounting is done only if that branch is successfull (terminates with a 2xx reply code).

The cgrates_acc() function should only be called on initial INVITEs. For more infirmation check Section 1.3, “Accounting”.

Meaning of the parameters is as follows:

  • flags - indicates whether OpenSIPS should generate a CDR at the end of the call. This parameter is optional, and if missing, no CDR is generated - the session is only passed through CGRateS. The following values can be used, separated by '|':

    • cdr - also generate a CDR;

    • missed - generate a CDR even for missed calls; this flag only makes sense if the cdr flag is used;

  • account - the account that will be charged in CGrateS. This parameter is optional, and if not specified, the user in the From header is used.

  • destination - the dialled number. Optional parameter, if not present the request URI user is used.

  • session - the tag of the session that will be started if the branch/call completes with success. This parameter indicates what set of data from the $cgr() variable should be considered. If missing, the default set is used.

The function can return the following values:

  • 1 - successful call - the CGRateS accouting was successfuly setup for the call.

  • -1 - OpenSIPS returned an internal error (i.e. the dialog cannot be created, or the server is out of memory).

  • -2 - the SIP message is invalid: either it has missing headers, or it is not an initial INVITE.

This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE.

Example 1.5. cgrates_acc() usage

		...
		if (!has_totag()) {
			...
			if (cgrates_auth("$fU", "$rU"))
				cgrates_acc("cdr|missed", "$fU", "$rU");
			...
		}
		...
		

1.8.2.  cgrates_auth([account[, destination[, session]]])

cgrates_auth() does call authorization through using the CGRateS engine.

Meaning of the parameters is as follows:

  • account - the account that will be checked in CGrateS. This parameter is optional, and if not specified, the user in the From header is used.

  • destination - the dialled number. Optional parameter, if not present the request URI user is used.

  • session - the tag of the session that will be started if the branch/call completes with success. This parameter indicates what set of data from the $cgr() variable should be considered. If missing, the default set is used.

The function can return the following values:

  • 1 - successful call - the CGRateS account is allowed to make the call.

  • -1 - OpenSIPS returned an internal error (i.e. server is out of memory).

  • -2 - the CGRateS engine returned error.

  • -3 - No suitable CGRateS server found. message type (not an initial INVITE).

  • -4 - the SIP message is invalid: either it has missing headers, or it is not an initial INVITE.

  • -5 - CGRateS returned an invalid message.

This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE.

Example 1.6. cgrates_auth() usage

		...
		if (!has_totag()) {
			...
			if (!cgrates_auth("$fU", "$rU")) {
				sl_send_reply("403", "Forbidden");
				exit;
			}
			...
		}
		...
		

1.8.3.  cgrates_cmd(command[, session])

cgrates_cmd() can send arbitrary commands to the CGRateS engine.

Meaning of the parameters is as follows:

  • command - the command sent to the CGRateS engine. This is a mandatory parameter.

  • session - the tag of the session that will be started if the branch/call completes with success. This parameter indicates what set of data from the $cgr() variable should be considered. If missing, the default set is used.

The function can return the following values:

  • 1 - successful call - the CGRateS account is allowed to make the call.

  • -1 - OpenSIPS returned an internal error (i.e. server is out of memory).

  • -2 - the CGRateS engine returned error.

  • -3 - No suitable CGRateS server found. message type (not an initial INVITE).

This function can be used from any route.

Example 1.7. cgrates_cmd() usage

		...
		# cgrates_auth("$fU", "$rU"); simulation
		$cgr(Tenant) = $fd;
		$cgr(Account) = $fU;
		$cgr(OriginID) = $ci;
		$cgr(SetupTime) = "" + $Ts;
		$cgr(RequestType) = "*prepaid";
		$cgr(Destination) = $rU;
		cgrates_cmd("SMGenericV1.GetMaxUsage");
		xlog("Call is allowed to run $cgrret seconds\n");
		...
		

1.9. Exported pseudo-variables

1.9.1. $cgr(name) / $(cgr(name)[session])

Pseudo-variable used to set different parameters for the CGRateS command. Each name-value pair will be encoded as a string - value attribute in the JSON message sent to CGRateS.

The name-values pairs are stored in the transaction (if tm module is loaded). Therefore the values are accessible in the reply.

When the cgrates_acc() function is called, all the name-value pairs are moved in the dialog. Therefore the values will be accessible along the dialog's lifetime.

This variable consists of serveral sets of name-value pairs. Each set corresponds to a session. The variable can be indexed by a session tag. The sets are completely indepdendent from one another. if the session tag does not exist, the default (no name) one is used.

Example 1.8. $cgr(name) simple usage

		...
		if (!has_totag()) {
			...
			$cgr(Tenant) = $fd; # set the From domain as a tenant
			$cgr(RequestType) = "*prepaid"; # do prepaid accounting
			if (!cgrates_auth("$fU", "$rU")) {
				sl_send_reply("403", "Forbidden");
				exit;
			}
		}
		...
		

Example 1.9. $cgr(name) multiple sessions usage

		...
		if (!has_totag()) {
			...
			# first session - authorize the user
			$cgr(Tenant) = $fd; # set the From domain as a tenant
			$cgr(RequestType) = "*prepaid"; # do prepaid accounting
			if (!cgrates_auth("$fU", "$rU")) {
				sl_send_reply("403", "Forbidden");
				exit;
			}

			# second session - authorize the carrier
			$(cgr(Tenant)[carrier]) = $td;
			$(cgr(RequestType)[carrier]) = "*postpaid";
			if (!cgrates_auth("$tU", "$fU", "carrier")) {
				# use a different carrier
				return;
			}

			# if everything is successfull, start accounting on both
			cgrates_acc("cdr", "$fU", "rU");
			cgrates_acc("cdr", "$tU", "$fU", "carrier");
		}
		...
		

1.9.2. $cgrret

Returns the reply message of a CGRateS command in script.

Example 1.10. $cgrret usage

		...
		cgrates_auth("$fU", "$rU");
		xlog("Call is allowed to run $cgrret seconds\n");
		...
		

1.10. Exported Asynchronous Functions

1.10.1.  cgrates_auth([account[, destination[, session]]])

Does the CGRateS authorization call in an asynchronous way. Script execution is suspended until the CGRateS engine sends the reply back.

Meaning of the parameters is as follows:

  • account - the account that will be checked in CGRateS. This parameter is optional, and if not specified, the user in the From header is used.

  • destination - the dialled number. Optional parameter, if not present the request URI user is used.

  • session - the tag of the session that will be started if the branch/call completes with success. This parameter indicates what set of data from the $cgr() variable should be considered. If missing, the default set is used.

The function can return the following values:

  • 1 - successful call - the CGRateS account is allowed to make the call.

  • -1 - OpenSIPS returned an internal error (i.e. server is out of memory).

  • -2 - the CGRateS engine returned error.

  • -3 - No suitable CGRateS server found. message type (not an initial INVITE).

  • -4 - the SIP message is invalid: either it has missing headers, or it is not an initial INVITE.

  • -5 - CGRateS returned an invalid message.

Example 1.11. async cgrates_auth usage

route {
	...
	async(cgrates_auth("$fU", "$rU"), auth_reply);
}

route [auth_reply]
{
	if ($rc < 0) {
		xlog("Call not authorized: code=$cgrret!\n");
		send_reply("403", "Forbidden");
		exit;
	}
	...
}

1.10.2.  cgrates_cmd(command[, session])

Can run an arbitrary CGRateS command in an asynchronous way. The execution is suspended until the CGRateS engine sends the reply back.

Meaning of the parameters is as follows:

  • command - the command sent to the CGRateS engine. This is a mandatory parameter.

  • session - the tag of the session that will be started if the branch/call completes with success. This parameter indicates what set of data from the $cgr() variable should be considered. If missing, the default set is used.

The function can return the following values:

  • 1 - successful call - the CGRateS account is allowed to make the call.

  • -1 - OpenSIPS returned an internal error (i.e. server is out of memory).

  • -2 - the CGRateS engine returned error.

  • -3 - No suitable CGRateS server found. message type (not an initial INVITE).

Example 1.12. async cgrates_cmd usage

route {
	...
	$cgr(Tenant) = $fd;
	$cgr(Account) = $fU;
	$cgr(OriginID) = $ci;
	$cgr(SetupTime) = "" + $Ts;
	$cgr(RequestType) = "*prepaid";
	$cgr(Destination) = $rU;
	async(cgrates_cmd("SMGenericV1.GetMaxUsage"), auth_reply);
}

route [auth_reply]
{
	if ($rc < 0) {
		xlog("Call not authorized: code=$cgrret!\n");
		send_reply("403", "Forbidden");
		exit;
	}
	...
}

Chapter 2. Contributors

2.1. By Commit Statistics

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

 NameDevScoreCommitsLines ++Lines --
1. Razvan Crainea (@razvancrainea)1274961681595
2. Bogdan-Andrei Iancu (@bogdan-iancu)531719
3. Liviu Chircu (@liviuchircu)31414
4. Vlad Patrascu (@rvlad-patrascu)3144

(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

 NameCommit Activity
1. Razvan Crainea (@razvancrainea)Dec 2016 - Jul 2018
2. Liviu Chircu (@liviuchircu)Jun 2018 - Jun 2018
3. Vlad Patrascu (@rvlad-patrascu)Apr 2018 - Apr 2018
4. Bogdan-Andrei Iancu (@bogdan-iancu)Mar 2017 - Sep 2017

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

Chapter 3. Documentation

3.1. Contributors

Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea).

doc copyrights:

Copyright © 2017 Răzvan Crainea