Collect Call Charging Service Example

This example configuration is for a collect call charging service that implements reverse call charges. Instead of charging the A-party (the calling party), MATRIXX charges the B-party (the called party) for calls initiated by the A-party.

In this example, MATRIXX invokes the collect call service functionality when it receives an InitialDP (IDP) that has a special prefix of B222 in the callingParty field. MATRIXX processes the call as follows:

  1. When a call arrives that includes the collect call prefix in the callingParty field of the IDP, the MSC sends the IDP to MATRIXX to process as an MT call. The callingParty field is set to the A-party, and the calledParty field is set to the B-party.
  2. MATRIXX authorizes the call and begins the ApplyCharging process.
  3. When the B-party answers the call, MATRIXX connects to an external IVR. MATRIXX also plays an announcement configured in a post-answer announcement menu to the B-party asking them to accept or release the call, and waits for a response. A response of:
    • 1 means the B-party accepts the call.
    • 2 means the B-party rejects the call.
  4. If the B-party accepts the call:
    • MATRIXX returns a TCAP Continue message to the MSC.
    • MATRIXX looks up the B-party in the MATRIXX database and applies charging to the B-party.
  5. If the B-party rejects the call, MATRIXX returns a TCAP Release message to the MSC to release the call.
In this example, the customer defines configuration in create_config.info. This configuration creates another voice service named collect_call and configures selective updates to trigger the service for MT calls with service key 333.

The following lines in create_config.info configure the collect_call voice service:

How many additional voice services do you wish to create?1
Camel Gateway:VCS Additional 1:What is the name identifier of this service?collect_call
...
Camel Gateway:VCS collect_call:Should oDisconnect or tDisconnect for leg 2 be armed as interrupted for this service (y/n)?y
...
Camel Gateway:VCS collect_call:Should an alternative message sequence be used for this service (y/n)?y
Camel Gateway:VCS collect_call:Which type of alternative message sequence should be used for this service?type3
Camel Gateway:VCS collect_call:Do you want to play announcements in this service (y/n)?y
...
Camel Gateway:VCS collect_call:What subscriber sources are required for this service?imsi
...
Camel Gateway:VCS collect_call:How many selectors do you wish to create for this service?2
Camel Gateway:VCS collect_call:Selector 1:What is the calling SCCP global title prefix for this selector?any_or_not_present
Camel Gateway:VCS collect_call:Selector 1:What is the calling SCCP point code for this selector?any_or_not_present
Camel Gateway:VCS collect_call:What is the SCCP Subsystem number for this selector?146
Camel Gateway:VCS collect_call:What is the TCAP Application Context for this selector?any
Camel Gateway:VCS collect_call:Selector 1:What is the IDP Service Key for this selector?333
Camel Gateway:VCS collect_call:Selector 1:What is the IDP Event Detection Point for this selector?termAttemptAuthorized
Camel Gateway:VCS collect_call:Selector 2:What is the calling SCCP global title prefix for this selector?any_or_not_present
Camel Gateway:VCS collect_call:Selector 2:What is the calling SCCP point code for this selector?any_or_not_present
Camel Gateway:VCS collect_call:Selector 2:What is the SCCP Subsystem number for this selector?146
Camel Gateway:VCS collect_call:Selector 2:What is the TCAP Application Context for this selector?cap2
Camel Gateway:VCS collect_call:Selector 2:What is the IDP Service Key for this selector?333
Camel Gateway:VCS collect_call:Selector 2:What is the IDP Event Detection Point for this selector?termAttemptAuthorized

Assuming that IDPs may come in with a different service key, the following example selective update changes the service key to 333 if the calling party IDP starts with B222.

SelectiveUpdate:ChargingServer:Input:What are the element IDs?1
SelectiveUpdate:ChargingServer:Input:Element 1:Enter an optional description of what this element is doing?If IDP.callingPartyNumber starts with B222 then change IDP.serviceKey to 333.
SelectiveUpdate:ChargingServer:Input:Element 1:What is the container's name?MtxTcapMsg
SelectiveUpdate:ChargingServer:Input:Element 1:What are the selection key IDs?1;2
SelectiveUpdate:ChargingServer:Input:Element 1:SelectionKey 1:What method do you want to perform?all
SelectiveUpdate:ChargingServer:Input:Element 1:SelectionKey 1:What is the sequence's name?main:InTcapInfo.BeginData.ComponentList
SelectiveUpdate:ChargingServer:Input:Element 1:SelectionKey 1:What action do you want to take on a match?select
SelectiveUpdate:ChargingServer:Input:Element 1:SelectionKey 2:What method do you want to perform?regex_search
SelectiveUpdate:ChargingServer:Input:Element 1:SelectionKey 2:What is the sequence's name?
SelectiveUpdate:ChargingServer:Input:Element 1:SelectionKey 2:What is the field's name?selected:ExecuteData.TcapParameter.MtxAsn1Cap2InitialDPParameterData:CallingStationId.AddressContent
SelectiveUpdate:ChargingServer:Input:Element 1:SelectionKey 2:What is the field value?^B222
SelectiveUpdate:ChargingServer:Input:Element 1:SelectionKey 2:What regular expression options do you want to use?match_posix
SelectiveUpdate:ChargingServer:Input:Element 1:How many operations do you want to enter?1
SelectiveUpdate:ChargingServer:Input:Element 1:Operation 1:What operation do you want to perform?set_field
SelectiveUpdate:ChargingServer:Input:Element 1:Operation 1:SetField:What is the destination field's name?selected:ExecuteData.TcapParameter.MtxAsn1Cap2InitialDPParameterData:ServiceKey
SelectiveUpdate:ChargingServer:Input:Element 1:Operation 1:SetField:What is the new value?333
The customer also configures a post-answer announcement menu for the collect_call service. This configuration plays an announcement to the B-party after the call is answered and then waits for a response. The B-party can then decide whether to accept or reject the call.
Note: CCF uses a non-standard message sequence for implementing post-answer announcement menus that is not supported by standards compliant MSCs or SSPs. The service supports only MSCs or SSPs that have been modified to use this message sequencing.
For more information about post-announcement menu configuration, see the discussion about post-answer announcement menus.
In this example, the collect_call post-answer announcement menu is implemented by the following Apache FreeMarker Template (ftl) files:
  • mtxMenuNotification.ftl
  • mtx200MainMenu.ftl
  • mtx200Main.ftl

For information about configuring ftl files, see the discussion about Apache FreeMarker template configuration.

When the mtxMenuNotification.ftl notification is triggered by the announcement menu service, it either invokes one of the following:
  • The mtx200MainMenu.ftl file to play the menu announcements.
  • The mtx200Main.ftl file to process the B-party reponses.
To configure the post-answer menu to trigger after the B-party has answered, the Start Menu Action After Call Is Answered check box must be selected. Select this in the PostRating profile containing the menu action that starts the menu. For this example, the service code for the menu action must be set to 200 to correspond with this section of the mtxMenuNotification.ftl file:
<#switch body.serviceCode>
    <#case 200>
This example also assumes that the PostRating profile ID 1999, referred to in the following line in the mtxMenuNotification.ftl file:
<#t>${request.setHeader('announcementProfileId', '1999')}
has an announcement detail record with an announcement variable that plays the A-party number held in the CallingStationId field of the MtxDiamRoMsg MDC.

The mtxMenuNotification.ftl file is shown below:

<#setting output_encoding="UTF-8">
<#-- ------------------------------------------------ -->
<#--  We currently support SC (service code) 200      -->
<#--  Header values that can be set                   -->
<#--  TODO                                            -->
<#-- ------------------------------------------------ -->
<#t>${request.setHeader('CamelHttpMethod', 'ZERO')}
<#if body.result == 3>

  <#-- ---------------------------------------------------- -->
  <#-- Switch on the SC selected by the user                -->
  <#-- ---------------------------------------------------- -->
  <#switch body.serviceCode>
    <#case 200>
      <#if body.logicalState == 0>

        <#-- ---------------------------------------------------- -->
        <#-- Play the introductory announcement                   -->
        <#-- ---------------------------------------------------- -->
        <#t>${request.setHeader('xmlLogicalState', '200')}
        <#t>${request.setHeader('announcementProfileId', '1999')}
        <#t>${request.setHeader('onSuccessEndOfMenuFlags','sendMenu')}
        <#t>${request.setHeader('onFailureEndOfMenuFlags','releaseCall')}
        <#include "mtx200MainMenu.ftl">
      <#else>

        <#-- ---------------------------------------------------- -->
        <#-- Otherwise just process the user's selections         -->
        <#-- ---------------------------------------------------- -->
        <#include "mtx200Main.ftl">
      </#if>
      <#break>
  <#default>
    Unknown USSD Service code, call customer care.
    <#t>${request.setHeader('announcementProfileId', '1998')}
  </#switch>
</#if>
The mtx200MainMenu.ftl file lists the announcements to play to the B-party.
Press 1 to release the call.
Press 2 to continue the call.
The mtx200Main.ftl file processes the B-party responses.
<#-- --------------------------------------------------------------------------- -->
<#--  mtx200Main.ftl Switch on logical state                                     -->
<#--                                                                             -->
<#-- To exit USSD set header <#t>${request.setHeader('newEndOfMenuFlags', '17')} -->
<#-- --------------------------------------------------------------------------- -->
<#-- <#switch body.logicalState> -->
<#switch headers.xmlLogicalState?number>

  <#-- -------------------------------------------------------- -->
  <#--    SC 200, Case LogicalState-200 process Main Menu       -->
  <#--                                                          -->
  <#--    Press 1 to release the call.                          -->
  <#--    Press 2 to continue the call.                         -->
  <#-- -------------------------------------------------------- -->
  <#case 200>
    <#t>${request.setHeader('xmlLogicalState', '250')}
    <#t>${request.setHeader('announcementProfileId', '5')}
    <#t>${request.setHeader('onSuccessEndOfMenuFlags','sendMenu')}
    <#t>${request.setHeader('onFailureEndOfMenuFlags','releaseCall')}
    Bye
    <#break>
  
  <#-- ------------------------------------------------------------------- -->
  <#--    SC 200, Process menu answer without playing an announcement.     -->
  <#--                                                                     -->
  <#--    1 => release the call.                                           -->
  <#--    2 => contine and charge for the call.                            -->
  <#--  ------------------------------------------------------------------ -->
  <#case 250>
    <#t>${request.setHeader('announcementProfileId', '0')}
    <#if body.receivedInfo == '1'>
      <#t>${request.setHeader('xmlLogicalState', '0')}
      <#t>${request.setHeader('onSuccessEndOfMenuFlags','reauthorizeAndCharge')}
      <#t>${request.setHeader('onFailureEndOfMenuFlags','releaseCall')}
    <#elseif body.receivedInfo == '2'>
      <#t>${request.setHeader('xmlLogicalState', '0')}
      <#t>${request.setHeader('onSuccessEndOfMenuFlags','releaseCall')}
      <#t>${request.setHeader('onFailureEndOfMenuFlags','releaseCall')}
    <#else>
      <#t>${request.setHeader('xmlLogicalState', '0')}
      <#t>${request.setHeader('onSuccessEndOfMenuFlags','releaseCall')}
      <#t>${request.setHeader('onFailureEndOfMenuFlags','releaseCall')}
    </#if>
    <#break>

  <#-- -------------------------------------------------------------- -->
  <#--    SC 200, Default Case/Switch, exit                           -->
  <#--  ------------------------------------------------------------- -->
  <#default>
    Unknown USSD Service code, call customer care.
    <#t>${request.setHeader('announcementProfileId', '1998')}
    <#t>${request.setHeader('onSuccessEndOfMenuFlags','releaseCall')}
    <#t>${request.setHeader('onFailureEndOfMenuFlags','releaseCall')}

</#switch>