Calling Operations Module


Table of Contents

1. Admin Guide
1.1. Overview
1.2. Dependencies
1.2.1. OpenSIPS Modules
1.2.2. External Libraries or Applications
1.3. Exported Parameters
1.3.1. mode (string/integer)
1.3.2. match_param (string)
1.4. Exported Functions
1.4.1. call_blind_replace(callid[, leg])
1.4.2. call_transfer_notify()
1.4.3. call_transfer(leg, destination) or
1.4.4. call_transfer(leg, transfer_callid, transfer_leg[, destination]) or
1.5. Exported MI Functions
1.5.1. call_transfer
1.5.2. call_hold
1.5.3. call_unhold
1.6. Exported Events
1.6.1. E_CALL_TRANSFER
1.6.2. E_CALL_HOLD
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. Drop automatically handled NOTIFY refer events
1.2. Set mode parameter
1.3. Set match_param parameter
1.4. Use call_blind_replace() function to match an existing leg.
1.5. Use call_transfer_notify() function to handle NOTIFY refer requests.
1.6. Use call_transfer() function to do a blind transfer of the caller to a new destination.
1.7. Use call_transfer() function to do an attended transfer of the caller to the callee of a different call.

Chapter 1. Admin Guide

1.1. Overview

This module provides a set of functions that allow the user to control ongoing calls. It can be used to trigger a call (either blind or attended) transfer, or put a call on hold from the proxy side, rather than the end-device side. The module binds on top of the OpenSIPS Dialog module to get information about the ongoing calls, as well as storing information about new calls that will be started.

The module also triggers a set of events over Event Interface, providing to external applications details about how calls are being transferred, and how they link between them. These events can be used to track down all the legs involved in a call transfer.

One of the biggest challenge when doing Call Transfer scenarios is linking new calls to the old calls being transferred, especially in blind call transfer scenarios. In order to solve this challenge, the module can be configured to refer old legs in two different modes, changeable using the mode parameter:

  • Automatically (default mode), by adding a special parameter to the destination URI that is being sent in the REFER. When the new call comes back, the parameter will be present in the Request URI of the new call. The module will find it, link the new call to the old call, and remove the parameter from the URI.

  • Manually, by using custom/external logic (such as a database, or local storage), to match the old call. In this mode, the user has to explicitly call the call_blind_replace() function to link the two calls together.

The module can also be used to catch Notify refer events and reply to them from the OpenSIPS level. However, note that in auto mode even if the NOTIFY is handled when the dialog is matched, the request will still continue its execution of the script, unlike when manual mode is used with the call_transfer_notify() function. In order to avoid sending the NOTIFY to the end-point, you have to drop it, like below:

Example 1.1. Drop automatically handled NOTIFY refer events

...
if (has_totag() && loose_route() &&
		is_method("NOTIFY") && $hdr(Event) == "refer")
	drop;
...


1.2. Dependencies

1.2.1. OpenSIPS Modules

The following modules must be loaded before this module:

  • TM - Transaction module.

  • Dialog - Dialog module for keeping track of the proxied calls.

1.2.2. External Libraries or Applications

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

  • None.

1.3. Exported Parameters

1.3.1. mode (string/integer)

This parameter can be used to change the mode that the module uses to match a transferred leg. Supported values are:

  • param / 0 - when doing a blind transfer, the destination sent in the refer message will contain a parameter used to identify the dialog that is being replaced. this parameter will be automatically removed when the new call is received.

  • manual / 1 - the user will create its own logic to match the new calls, and will call the call_blind_replace() function to make OpenSIPS aware of the pair. Note that this mode does not handle automatically the Notify refer either, so you also have to use the call_transfer_notify() function to handle them.

  • callid / 2 - similar to the param value, except that instead of storing in the Request URI the dialog id of the call to be transfered, the actual callid is used as identifier.

Default value is 0 (auto mode using parameters).

Example 1.2. Set mode parameter

...
modparam("callops", "mode", "manual") # use your own logic
...

1.3.2. match_param (string)

The parameter used to match the different calls together. This is mainly using in the param mode, but it is also used internally to store different values inside the transferred dialog - make sure it does not overlap with existing dialog values.

Default value is osid.

Example 1.3. Set match_param parameter

...
modparam("callops", "match_param", "call")
...

1.4. Exported Functions

1.4.1.  call_blind_replace(callid[, leg])

When manual mode is used, this function is called to create a mapping between the transferring call and the transferred call. It should be called when OpenSIPS receives a new call that is transferring an existing call.

Parameters:

  • callid (string) - the existing call that is being transferred.

  • leg (string, optional) - the leg that is being transferred. If not specified, and OpenSIPS cannot determine the leg based on its destination, the unknown tag should be used.

This function can be used only from a request route.

Example 1.4. Use call_blind_replace() function to match an existing leg.

...
if (!has_totag() && is_method("INVITE")) {
	if (cache_fetch("local", "callid_$si", $avp(callid))) {
		call_blind_replace($avp(callid));
	}
}
...
	

1.4.2.  call_transfer_notify()

When manual mode is used, this function should be called on in-dialog NOTIFY requests for an Event: refer header, to handle them accordingly.

Note that if the function successfully handles the NOTIFY request, the script no longer continues its execution.

This function can be used from a request route, failure route and local route.

Example 1.5. Use call_transfer_notify() function to handle NOTIFY refer requests.

...
if (has_totag() && is_method("NOTIFY") && loose_route()) {
	call_transfer_notify();
}
...
	

1.4.3.  call_transfer(leg, destination) or

This function triggers a blind call transfer by sending a REFER message during an ongoing call. The function needs to be run inside the context of the dialog you are transferring.

Parameters:

  • leg (string) - the leg that is being transferred. Must be one of the caller or callee values.

  • destination (string) - SIP URI of the destination where the leg is being transferred.

This function can be used from any route that has a dialog context.

Example 1.6. Use call_transfer() function to do a blind transfer of the caller to a new destination.

...
if (has_totag() && && loose_route()) {
	call_transfer("caller", "sip:announcement@127.0.0.1");
}
...
	

1.4.4.  call_transfer(leg, transfer_callid, transfer_leg[, destination]) or

This function triggers an attended call transfer by sending a REFER message during an ongoing call. The function needs to be run inside the context of the dialog you are transferring.

Parameters:

  • leg (string) - the leg that is being transferred. Must be one of the caller or callee values.

  • transfer_callid (string) - the callid of the second dialog that is being transferred.

  • transfer_leg (string) - the leg within the second call that will be transferred to leg. Must be one of the caller or callee values.

  • destination (string, optional) - SIP URI of the destination where the leg is being transferred. If missing, the From/To URI of the initial call are used.

This function can be used from any route that has a dialog context.

Example 1.7. Use call_transfer() function to do an attended transfer of the caller to the callee of a different call.

...
if (has_totag() && && loose_route()) {
	call_transfer("caller", "ba55b1b3-459d-4e84-a6f8-14c40e4f6ace", "callee");
}
...
	

1.5. Exported MI Functions

1.5.1.  call_transfer

MI command to transfer an ongoing call to a new destination.

Depending on the parameters used, this command can do both blind and attended transfers scenarios. When the transfer_callid is used, then an attended transfer is performed, other wise a blind transfer is issued.

Name: call_transfer

Parameters

  • callid (string) - the callid of the dialog that is being transferred.

  • leg (string) - indicates the leg of the callid call that is being transferred/kept in the new transferring call. Possible values are caller, callee or both.

  • destination (string, optional) - the URI where the call is being transferred. This parameter is mandatory for blind transfers, and optional for attended transfers. In the case of an attended transfer, if it is missing, the destination of the call is taken from the URIs in the transfer dialog.

  • transfer_callid (string, optional) - mandatory in case of an attended transfer, to specify the call of the Bleg in the new call.

  • transfer_leg (string, optional) - in case of an attended transfer, it specifies the participant of the transfer_callid call that will be bridged with the leg of the callid. If missing, transfer_fromtag and transfer_totag must be used to identify the tag.

  • transfer_fromtag and transfer_totag (string, optional) - these parameters should always be specified together, and are used in call attended transfer scenarios where the dialog of the Bleg that is being transferred is not managed by OpenSIPS. Note that for these scenarios only the A-leg dialog will receive events about the call transfer.

MI FIFO Command Format:

# blind transfer to sip:agent@127.0.0.1
opensips-cli -x mi call_transfer \
	callid=4b664b48-5639-40bf-bff8-3a866c145c3b \
	leg=caller \
	destination=sip:agent@217.0.0.1
		
# attended transfer between two calls
opensips-cli -x mi call_transfer \
	callid=e8d024db-78e5-4d18-9794-5b8ba837bed4
	leg=caller \
	transfer_callid=559abf97-9834-4380-bba1-a036eb245450 \
	transfer_leg=calee
		

1.5.2.  call_hold

MI command to put an ongoing call on hold.

Command returns OK if any of the legs of the call have been put on hold. If the call is already on hold, an error is returned.

Name: call_hold

Parameters

  • callid (string) - the callid of the dialog that is being put on hold.

MI FIFO Command Format:

# put a call on hold
opensips-cli -x mi call_hold \
	callid=921b00e4-fec0-4a36-9397-a40ab74e1893
		

1.5.3.  call_unhold

MI command to resume a call from an onhold state put by the call_hold call.

Command returns OK if any of the legs are resumed, or an error if no leg had been previously put on hold.

Name: call_unhold

Parameters

  • callid (string) - the callid of the dialog that is being resumed.

MI FIFO Command Format:

opensips-cli -x mi call_unhold \
	callid=921b00e4-fec0-4a36-9397-a40ab74e1893
		

1.6. Exported Events

1.6.1.  E_CALL_TRANSFER

This event is triggered during a call transfer scenario.

For a specific call transfer, multiple events are triggered, starting when the transfer is initiated, until the transfer is completed. The state parameter indicates the state of the call transfer.

For a blind transfer scenario, only one set of events are triggered, whereas for attended transfer, you will get a set of events for both dialogs involved in the transfer, as long as both are proxied through OpenSIPS

Parameters:

  • callid - the callid of the call that is being transferred.

  • leg - the leg (caller or callee) of the call that is being transferred.

  • transfer_callid - the callid of the new call that is transferring the old callid call.

  • destination - the URI destination where the leg is being transferred.

  • state - the state of the transfer:

    • start - triggered when the REFER message is being sent out to the transferred participant.

    • notify - triggered when a NOTIFY refer event is received from the transferred participant. The status parameter contains extra information about the status of the transferring call.

    • ok - triggered when the transfer is completed - the call is answered by the transferred participant.

    • fail - triggered when a transfer has failed due to various reasons. If we were unable to start the call transfer (i.e. send the REFER), the status parameter is empty, otherwise it contains information about the failure.

  • status - contains extra information about the success or failure of the call.

1.6.2.  E_CALL_HOLD

Triggered during the process of putting a call on hold, or resuming a call from an on hold state.

This event is triggered twice per each leg of the call - first when the leg starts to be put on hold, and then when the leg accepts or rejects the state.

Parameters:

  • callid - the callid of the call that is being put on hold, or resumed.

  • leg - the leg (caller or callee) affected by the call on hold, or resumed.

  • action - hold or unhold action that is being performed.

  • state - the state of the action that is being performed.

    • start - triggered when the re-INVITE is being sent out to the participant being put on hold.

    • ok - triggered when the on hold/resume action is successfully completed.

    • fail - triggered when the action failed.

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)45222267157
2. Vlad Patrascu (@rvlad-patrascu)5112366
3. Maksym Sobolyev (@sobomax)4245
4. Bogdan-Andrei Iancu (@bogdan-iancu)3121
5. Liviu Chircu (@liviuchircu)3111

(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. Bogdan-Andrei Iancu (@bogdan-iancu)Apr 2023 - Apr 2023
2. Vlad Patrascu (@rvlad-patrascu)Mar 2023 - Mar 2023
3. Maksym Sobolyev (@sobomax)Feb 2023 - Feb 2023
4. Liviu Chircu (@liviuchircu)Jan 2021 - Jan 2021
5. Razvan Crainea (@razvancrainea)May 2020 - Jul 2020

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

Chapter 3. Documentation

3.1. Contributors

Last edited by: Razvan Crainea (@razvancrainea).

Documentation Copyrights:

Copyright © 2020 www.opensips-solutions.com