Skip to main content

Supplementary Services

๐Ÿ“– Back to Main Documentation

Configuration and implementation of call forwarding, CLI blocking, and emergency calling services.

Core Documentationโ€‹

  • ๐Ÿ“‹ Main README - Overview and quick start
  • ๐Ÿ”ง Configuration Guide - Service configuration parameters (emergency codes, CLI blocking, default call forward)
  • ๐Ÿ”ง Operations Guide - Testing supplementary services

Call Processing & Data Sourcesโ€‹

Service Interactionsโ€‹

  • ๐Ÿ’ณ Online Charging - Emergency calls bypass OCS
  • ๐Ÿ“ž Voicemail - Call forward on busy/no-answer routes to voicemail

Monitoringโ€‹


Supplementary Services (Call Forward / Blocked CLI / Emergency Codes)โ€‹

Config for blocked CLI prefixes, emergency call codes, and default Call Forward data (Call Forward / No Reply data is only used when no MMTel-Config data is returned from the Repository on Sh).

config :tas,
...
blocked_cli_prefix: ["*67"],
call_forward_not_reachable_destination: "2222",
default_no_reply_timer: 30,
emergency_call_codes: ["911", "912", "913", "sos"],
...

Configuration Parameters:

  • blocked_cli_prefix (list of strings): Prefixes that trigger CLI (Calling Line ID) withholding

    • Example: ["*67"] - dialing *67 before a number hides caller ID
    • Used in dialplan to set cli_withheld variable
  • call_forward_not_reachable_destination (string): Default destination for Call Forward Not Reachable (CFNRc)

    • Only used when no MMTel-Config is returned from Sh interface
    • Example: "2222" - forwards to voicemail
  • default_no_reply_timer (integer): Default timeout in seconds before CFNRc activates

    • Only used when no MMTel-Config is returned from Sh interface
    • Example: 30 - rings for 30 seconds before forwarding
  • emergency_call_codes (list of strings): Emergency service numbers for your jurisdiction

    • Checked during call authorization to detect emergency calls
    • SIP emergency URNs (e.g., <urn:service:sos>) are always checked in addition to these codes
    • Common examples: ["911", "112", "000", "999", "sos"]
    • See Emergency Calling section for detailed usage

How Caller ID Blocking Worksโ€‹

The TAS supports two methods for blocking caller ID (CLI withholding), both of which set the cli_withheld dialplan variable to "true":

Method 1: Prefix-Based Blocking

When a subscriber dials a destination number prefixed with a code from blocked_cli_prefix:

  1. The number translation module detects the prefix (e.g., caller dials *67555123456)
  2. The prefix is stripped from the destination number (becomes 555123456)
  3. The cli_withheld variable is set to "true"
  4. The dialplan can then use this variable to hide the caller's identity

Example configuration:

blocked_cli_prefix: ["*67"]        # US-style blocking
blocked_cli_prefix: ["#31#"] # European GSM-style blocking
blocked_cli_prefix: ["*67", "#31#"] # Support both

Method 2: SIP From Header Detection

When the UE/handset requests privacy via SIP headers:

  1. The TAS checks if the SIP From header display name contains "anonymous" (case-insensitive)
  2. If found, the cli_withheld variable is set to "true"
  3. This honors the subscriber's privacy request set at the device level

Implementing CLI Blocking in Dialplan

The TAS sets the cli_withheld variable, but your dialplan XML must implement the actual blocking behavior:

<extension name="CLI-Privacy" continue="true">
<condition field="${cli_withheld}" expression="true">
<!-- Hide caller identity -->
<action application="set" data="effective_caller_id_name=anonymous"/>
<action application="set" data="effective_caller_id_number=anonymous"/>
<action application="set" data="origination_privacy=hide_number"/>

<!-- Optionally set P-Asserted-Identity privacy -->
<action application="set" data="sip_h_Privacy=id"/>
</condition>
</extension>

Variables Set by TAS for CLI Blocking:

The TAS sets these variables before dialplan execution:

VariableTypeValuesDescription
cli_withheldstring"true" or "false"Indicates if CLI blocking was requested via prefix OR From header
tas_destination_numberstringnormalized numberDestination with blocking prefix removed (e.g., 555123456)
destination_numberstringnormalized numberSame as tas_destination_number (both are set)

Variables Your Dialplan Should Set (when cli_withheld="true"):

These variables control how caller identity is presented:

VariableRecommended ValuePurpose
effective_caller_id_number"anonymous"Hides the caller's phone number
effective_caller_id_name"anonymous"Hides the caller's display name
origination_privacy"hide_number"SIP privacy flag for outbound leg
sip_h_Privacy"id"SIP Privacy header (RFC 3323)
sip_h_P-Asserted-Identity(unset or remove)Optional: Remove P-Asserted-Identity header

Complete Dialplan Example:

<extension name="CLI-Privacy-Handler" continue="true">
<condition field="${cli_withheld}" expression="true">
<!-- Log for troubleshooting -->
<action application="log" data="INFO CLI blocking requested for call to ${tas_destination_number}"/>

<!-- Hide caller identity on outbound call -->
<action application="set" data="effective_caller_id_name=anonymous"/>
<action application="set" data="effective_caller_id_number=anonymous"/>
<action application="set" data="origination_privacy=hide_number"/>

<!-- Set SIP Privacy headers -->
<action application="set" data="sip_h_Privacy=id"/>

<!-- Optional: Remove P-Asserted-Identity if present -->
<action application="unset" data="sip_h_P-Asserted-Identity"/>

<!-- Anti-action runs if cli_withheld is false -->
<anti-action application="log" data="DEBUG Using normal caller ID: ${msisdn}"/>
<anti-action application="set" data="effective_caller_id_number=${msisdn}"/>
</condition>
</extension>

<!-- This extension continues to the actual call routing -->
<extension name="Route-Outbound-Call">
<condition field="${tas_destination_number}" expression="^(.+)$">
<action application="bridge" data="sofia/gateway/trunk/${tas_destination_number}"/>
</condition>
</extension>

Important Notes:

  • Both methods can work simultaneously (prefix OR SIP header triggers blocking)
  • The prefix is always stripped from the destination number, even if dialplan doesn't implement privacy
  • The cli_withheld variable is a string ("true" or "false"), not a boolean
  • Call Forwarding / Blocked CLI behavior is implemented in your dialplan XML
  • The example config includes these features, but if you do not define them in your dialplan, they will not function
  • Variables are set during the MO (Mobile Originating) call flow only

How Call Forwarding Worksโ€‹

Call forwarding (also known as Communication Diversion or CDIV) allows subscribers to redirect incoming calls to another destination. The TAS supports multiple types of call forwarding with configurable behavior.

Types of Call Forwardingโ€‹

1. Call Forward All (CFA) - Unconditional Forwarding

  • Variable: call_forward_all_destination
  • When Active: All incoming calls are immediately forwarded
  • Priority: Checked first (after HLR forwarding)
  • Common Use: Subscriber wants all calls sent to another number
  • Example: Business calls forwarded to personal phone

2. Call Forward Busy (CFB)

  • When Active: Call forwarded when subscriber is already on a call
  • SIP Response: 486 Busy triggers forwarding
  • Common Use: Forward to voicemail when on another call

3. Call Forward No Reply (CFNRy)

  • Variable: no_reply_timer
  • When Active: Call forwarded after ringing for specified seconds with no answer
  • Timeout: Typically 15-30 seconds
  • Common Use: Forward to voicemail if not answered

4. Call Forward Not Reachable (CFNRc)

  • Variable: call_forward_not_reachable_destination
  • When Active: Subscriber is offline, unregistered, or unreachable
  • SIP Response: 480 Temporarily Unavailable
  • Common Use: Forward to voicemail when phone is off
  • Default: Configuration parameter used if no MMTel-Config

Data Source Priorityโ€‹

Call forwarding data is retrieved from multiple sources with this priority:

1. HLR Data (SS7 MAP)           [Highest Priority - overrides all]
โ†“ (if no HLR forwarding active)
2. MMTel-Config (Sh Interface) [Subscriber-specific settings from HSS]
โ†“ (if no MMTel-Config returned)
3. Configuration Defaults [Lowest Priority - fallback values]

Why This Priority?

  • HLR Data: Real-time forwarding status for roaming/network scenarios
  • MMTel-Config: Subscriber-configured preferences in IMS
  • Config Defaults: Network-wide fallback (typically voicemail)

Dialplan Variables for Call Forwardingโ€‹

VariableTypeSourceExample ValueDescription
call_forward_all_destinationstringSh/MMTel or "none""61403555123"CFA destination if active
call_forward_not_reachable_destinationstringSh/MMTel or config"2222"CFNRc destination (voicemail)
no_reply_timerintegerSh/MMTel or config30Seconds to ring before CFNRy
msrnstringHLR (MT only)"61400123456"MSRN or forwarded number from HLR
tas_destination_numberstringCalculated"2222"Actual routing destination (may be forwarding number)

Implementing Call Forwarding in Dialplanโ€‹

Example MT Dialplan with Call Forwarding:

<!-- Check for Call Forward All (highest priority after HLR) -->
<extension name="Check-CFA" continue="true">
<condition field="${call_forward_all_destination}" expression="^(?!none$).+$">
<action application="log" data="INFO Call Forward All active to ${call_forward_all_destination}"/>
<action application="set" data="tas_destination_number=${call_forward_all_destination}"/>
</condition>
</extension>

<!-- Attempt to bridge to subscriber -->
<extension name="Bridge-To-Subscriber">
<condition field="${msrn}" expression="^none$">
<!-- No MSRN, route to local subscriber -->
<action application="set" data="call_timeout=${no_reply_timer}"/>
<action application="bridge" data="sofia/internal/${tas_destination_number}@${scscf_address}"/>

<!-- If bridge fails, check forwarding -->
<action application="log" data="INFO Bridge failed, checking call forwarding"/>

<!-- Call Forward Not Reachable -->
<action application="set" data="forward_destination=${call_forward_not_reachable_destination}"/>
<action application="log" data="INFO Forwarding to ${forward_destination}"/>
<action application="answer"/>
<action application="voicemail" data="default default ${msisdn}"/>
</condition>
</extension>

Configuring Default Call Forwardingโ€‹

Set network-wide defaults in config/runtime.exs:

config :tas,
# Default CFNRc destination (used when no MMTel-Config)
call_forward_not_reachable_destination: "2222", # Voicemail access number

# Default timeout before CFNRy activates (used when no MMTel-Config)
default_no_reply_timer: 30 # Ring for 30 seconds

When Defaults Are Used:

  • Subscriber exists in HSS but has no MMTel-Config provisioned
  • Sh lookup succeeds but returns no call forwarding settings
  • New subscribers before call forwarding is configured

Troubleshooting Call Forwardingโ€‹

Problem: Calls not forwarding as expected

  1. Check Sh Data:

    • Use Web UI /sh_test to query subscriber
    • Verify MMTel-Config contains CDIV rules
    • Check call_forward_all_destination value
  2. Check Dialplan Variables:

    • Review call logs for variable values
    • Confirm call_forward_all_destination != "none"
    • Verify tas_destination_number is set to forwarding destination
  3. Check HLR Data (if SS7 MAP enabled):

    • Use Web UI /hlr to query subscriber
    • HLR forwarding overrides Sh data
    • Verify msrn variable doesn't contain unexpected forwarding number
  4. Check Configuration Defaults:

    • Verify call_forward_not_reachable_destination in config
    • Confirm default_no_reply_timer is appropriate
    • These only apply when no MMTel-Config exists

Problem: Forwarding loops

Symptoms: Call forwards to a number that forwards back, creating a loop

Prevention in Dialplan:

<!-- Track forwarding hop count -->
<extension name="Prevent-Forward-Loop" continue="true">
<condition field="${sip_h_X-Forward-Hop-Count}" expression="^$">
<action application="set" data="sip_h_X-Forward-Hop-Count=1"/>
<anti-action application="set" data="sip_h_X-Forward-Hop-Count=${expr(${sip_h_X-Forward-Hop-Count}+1)}"/>
</condition>
</extension>

<extension name="Check-Forward-Hop-Limit">
<condition field="${sip_h_X-Forward-Hop-Count}" expression="^([3-9]|[1-9][0-9]+)$">
<action application="log" data="ERROR Forwarding loop detected, hop count: ${sip_h_X-Forward-Hop-Count}"/>
<action application="hangup" data="LOOP_DETECTED"/>
</condition>
</extension>

Monitoring Call Forwardingโ€‹

Key Indicators:

  • High rate of calls to voicemail numbers
  • Pattern of calls timing out at no_reply_timer value
  • Calls consistently routed to same forwarding destinations

Useful Logs:

INFO Call Forward All active to 61403555123
INFO Forwarding to 2222
INFO Bridge failed, checking call forwarding

Business Intelligence:

  • Track forwarding activation rates by subscriber
  • Monitor voicemail usage patterns
  • Identify subscribers with unconditional forwarding