Preface

Document Conventions

This manual uses several conventions to highlight certain words and phrases and draw attention to specific pieces of information.

In PDF and paper editions, this manual uses typefaces drawn from the Liberation Fonts set. The Liberation Fonts set is also used in HTML editions if the set is installed on your system. If not, alternative but equivalent typefaces are displayed. Note: Red Hat Enterprise Linux 5 and later includes the Liberation Fonts set by default.

Typographic Conventions

Four typographic conventions are used to call attention to specific words and phrases. These conventions, and the circumstances they apply to, are as follows.

Mono-spaced Bold

Used to highlight system input, including shell commands, file names and paths. Also used to highlight key caps and key-combinations. For example:

To see the contents of the file my_next_bestselling_novel in your current working directory, enter the cat my_next_bestselling_novel command at the shell prompt and press Enter to execute the command.

The above includes a file name, a shell command and a key cap, all presented in Mono-spaced Bold and all distinguishable thanks to context.

Key-combinations can be distinguished from key caps by the hyphen connecting each part of a key-combination. For example:

Press Enter to execute the command.

Press to switch to the first virtual terminal. Press to return to your X-Windows session.

The first sentence highlights the particular key cap to press. The second highlights two sets of three key caps, each set pressed simultaneously.

If source code is discussed, class names, methods, functions, variable names and returned values mentioned within a paragraph will be presented as above, in Mono-spaced Bold. For example:

File-related classes include filesystem for file systems, file for files, and dir for directories. Each class has its own associated set of permissions.

Proportional Bold

This denotes words or phrases encountered on a system, including application names; dialogue box text; labelled buttons; check-box and radio button labels; menu titles and sub-menu titles. For example:

Choose System > Preferences > Mouse from the main menu bar to launch Mouse Preferences. In the Buttons tab, click the Left-handed mouse check box and click Close to switch the primary mouse button from the left to the right (making the mouse suitable for use in the left hand).

To insert a special character into a gedit file, choose Applications > Accessories > Character Map from the main menu bar. Next, choose Search > Find from the Character Map menu bar, type the name of the character in the Search field and click Next. The character you sought will be highlighted in the Character Table. Double-click this highlighted character to place it in the Text to copy field and then click the Copy button. Now switch back to your document and choose Edit > Paste from the gedit menu bar.

The above text includes application names; system-wide menu names and items; application-specific menu names; and buttons and text found within a GUI interface, all presented in Proportional Bold and all distinguishable by context.

Note the menu:>[] shorthand used to indicate traversal through a menu and its sub-menus. This is to avoid the difficult-to-follow 'Select from the Preferences ▸ ] sub-menu in the menu:System[ menu of the main menu bar' approach.

Mono-spaced Bold Italic or Proportional Bold Italic

Whether Mono-spaced Bold or Proportional Bold, the addition of Italics indicates replaceable or variable text. Italics denotes text you do not input literally or displayed text that changes depending on circumstance. For example:

To connect to a remote machine using ssh, type ssh username@domain.name at a shell prompt. If the remote machine is example.com and your username on that machine is john, type ssh john@example.com.

The mount -o remount file-system command remounts the named file system. For example, to remount the /home file system, the command is mount -o remount /home.

To see the version of a currently installed package, use the rpm -q package command. It will return a result as follows: package-version-release.

Note the words in bold italics above —username, domain.name, file-system, package, version and release. Each word is a placeholder, either for text you enter when issuing a command or for text displayed by the system.

Aside from standard usage for presenting the title of a work, italics denotes the first use of a new and important term. For example:

When the Apache HTTP Server accepts requests, it dispatches child processes or threads to handle them. This group of child processes or threads is known as a server-pool. Under Apache HTTP Server 2.0, the responsibility for creating and maintaining these server-pools has been abstracted to a group of modules called Multi-Processing Modules (MPMs). Unlike other modules, only one module from the MPM group can be loaded by the Apache HTTP Server.

Pull-quote Conventions

Two, commonly multi-line, data types are set off visually from the surrounding text.

Output sent to a terminal is set in Mono-spaced Roman and presented thus:

books        Desktop   documentation  drafts  mss    photos   stuff  svn
books_tests  Desktop1  downloads      images  notes  scripts  svgs

Source-code listings are also set in Mono-spaced Roman but are presented and highlighted as follows:

package org.jboss.book.jca.ex1;

import javax.naming.InitialContext;

public class ExClient
{
   public static void main(String args[])
       throws Exception
   {
      InitialContext iniCtx = new InitialContext();
      Object         ref    = iniCtx.lookup("EchoBean");
      EchoHome       home   = (EchoHome) ref;
      Echo           echo   = home.create();

      System.out.println("Created Echo");

      System.out.println("Echo.echo('Hello') = " + echo.echo("Hello"));
   }

}

Notes and Warnings

Finally, we use three visual styles to draw attention to information that might otherwise be overlooked.

Note

A note is a tip or shortcut or alternative approach to the task at hand. Ignoring a note should have no negative consequences, but you might miss out on a trick that makes your life easier.

Important

Important boxes detail things that are easily missed: configuration changes that only apply to the current session, or services that need restarting before an update will apply. Ignoring Important boxes won’t cause data loss but may cause irritation and frustration.

Warning

A Warning should not be ignored. Ignoring warnings will most likely cause data loss.

Provide feedback to the authors!

If you find a typographical error in this manual, or if you have thought of a way to make this manual better, we would love to hear from you! Please submit a report in the the {this-issue.tracker.ur}, against the product Restcomm CAMEL Gateway` `, or contact the authors.

When submitting a bug report, be sure to mention the manual’s identifier: Restcomm CAMEL Gateway

If you have a suggestion for improving the documentation, try to be as specific as possible when describing it. If you have found an error, please include the section number and some of the surrounding text so we can find it easily.

1. Introduction to Restcomm CAMEL Gateway

Restcomm CAMEL Gateway is an Open Source Java based CAMEL Gateway Platform enabler intended for fast and easy Intelligent Networks (IN) services deployment in mobile networks using CAMEL Application Part (CAP) protocols. It enables operators to offer real-time control of voice call, SMS and GPRS sessions in GSM networks, using service logic applications.

Restcomm CAMEL Gateway strictly adheres to the standards and specifications defined by the International Telecommunications Union (ITU).

Restcomm CAMEL Gateway acts as an intermediary platform linking the service applications to the GSM network in a session oriented communication.

Restcomm CAMEL Gateway is an easy-to-install and easy-to-deploy platform. The Open Source Software gives you the flexibility to understand the source code. It is also possible to customise the product to meet your Enterprise needs.

Restcomm CAMEL Gateway is based on the robust and proven Restcomm JAIN SLEE 1.1 Server and Restcomm jSS7 Stack.

This guide provides detailed information about configuration, supported protocols and compliant standards. For installation instructions, please refer to the Installation Guide that is included in the product documentation. For more details about the underlying jSS7 Stack, you can refer to the Restcomm jSS7 Stack User Guide.

2. Overview

2.1. CAMEL

CAMEL stands for Customized Applications for Mobile networks Enhanced Logic. It is a set of standards designed to work on either a GSM core network or on a UMTS network. CAMEL allows an operator to define services over standard GSM services/UMTS services. The CAMEL architecture is based on the Intelligent network (IN) standards, and uses the CAP protocol.

Many services can be created using CAMEL, especially, services relating to roaming subscribers. The list below is an example of some of these services:

Virtual Private Network (VPN)

CAMEL enables a mobile VPN that simulates PBX-like dialing in a mobile environment. For example, a subscriber can dial "9901" and the call will be send to user Amit Bhayani at 996063-9901.

Call Redirect Services (CRS)

CAMEL is utilized to provide a variety of CRS services including redirecting international roaming subscribers to their desired customer care when they dial “123”

Conditional Call Forwarding

Calls can be forwarded to another subscriber if the called party is busy or not available. You also have to option to perform unconditional calls.

SMS

CAMEL also allows you to fine-tune SMS and billing

2.2. CAMEL Entities

The main entities involved in CAMEL are

Service Switching Function (SSF)

The IN control protocol at the exchange is handled by the service switching function (SSF). The SSF passes call control from the exchange to the SCP and relays instructions from the SCP back to the exchange. All IN protocol aspects are handled by the SSF. Figure below depicts the SSF in an MSC.

Service Control Function (SCF)

The service control function (SCF) is the functional entity residing in the service control plane (SCP). It forms an application in the SCP that facilitates the execution of IN services. The SCP is an addressable node in the SS7 network. Other nodes in the network may communicate with the SCP through the SS7 signaling protocol.

SSF inside MSC

For example a subscriber may dial *122 to reach a specific USSD service which is deployed in the home network. The application may reply with a menu based on the dialed short code. One of the advantages of this service is that it is always available even when the subscriber is roaming.

2.3. CAMEL Gateway

Restcomm CAMEL Gateway forms part of SCF. Restcomm CAMEL Gateway maintains the CAP Dialog and state modal, however it forwards the received CAP request over HTTP as XML payload to configured Application.

The application handles business logic and responds with a corresponding CAP message. The diagram below shows all the nodes involved

Restcomm camel gw

2.4. Major Features of Restcomm CAMEL Gateway

Restcomm 's implementation of CAMEL Gateway is the first and only open source CAMEL Gateway with a host of rich features and advantages.

Java-based

Restcomm CAMEL Gateway is the only Java based CAMEL Gateway. It is robust, reliable and can be installed on any Operating System that supports Java (JDK 7 and SCTP).

Open Source

The Software is open-source, therefore, you get access to the source code and you also have the added value of being able to customize its features to your enterprise needs. Additionally, there is an active community providing product support.

SS7 Hardware Cards

Restcomm CAMEL Gateway can be used with Restcomm SS7 boards or Intel family boards (Dialogic SS7 cards) or Zaptel/Dahdi compatible TDM devices (Digium, Sangoma).

SIGTRAN (M3UA)

It also has in-built support for SIGTRAN (M3UA using SCTP).

Easy Configuration and Management

Restcomm CAMEL Gateway comes with an efficient Command Line Interface (CLI) tool allowing you to easily configure the gateway at run-time and manage it using simple intuitive commands.

  • Restcomm CAMEL Gateway is easily scalable with a configurable load-balancing and high available architecture.

Technical Specifications

Restcomm CAMEL Gateway is not restricted by any license or Transaction Per Second model. The only restricting factor is memory + CPU capacity of the host servers, third-party applications or the underlying database service.

  • Restcomm CAMEL Gateway supports as many as 1,073,741,823 incoming and 1,073,741,823 outgoing concurrent sessions/dialogs.

  • Restcomm CAMEL Gateway supports unlimited E1 links and the only limiting factor is the underlying TDM board used.

  • Restcomm CAMEL Gateway SCTP supports as many associations as supported by the underlying Operating System.

  • Restcomm CAMEL Gateway M3UA can be configured to have as many ASP’s / IPSP’s as needed by the system.

  • Restcomm CAMEL Gateway SCCP can be configured to have virtually unlimited Global Title Translation rules and also supports wild characters for partial matching of Global Title digits.

HTTP Transfer Mechanism

The Restcomm CAMEL Gateway makes use of HTTP protocol between the gateway and the third-party applications. Restcomm CAMEL Gateway receives CAMEL request from the GSM Signaling network and then translates these requests to HTTP. The third-party application can be either of the following technologies on any Operating System:

  • Apache Tomcat, JBoss AS, Oracle Application Server, IBM Websphere etc for JSP/Servlet on Java

  • PHP

  • Microsoft IIS for ASP

Multi tenancy support

Same instance of Restcomm CAMEL Gateway can connect to different operators (MNO) and request from each can be directed to corresponding Application. For further details refer to Multi tenancy support

3. Architecture

Restcomm CAMEL Gateway is based on the robust and proven Restcomm JAIN SLEE 1.1 Server and Restcomm jSS7 Stack.

Restcomm JAIN SLEE Server is a highly scalable event-driven application server with a robust component model and fault tolerant execution environment. It provides a set of connectors to a variety of networks elements like SS7 MAP, TCAP, INAP, ISUP, SMPP, XMPP, SIP, MGCP, HTTP, XDM, XCAP, Diameter and many others. Restcomm JAIN SLEE Server is fully compliant with JSR 240 (JSLEE 1.1).

Restcomm jSS7 is a software based implementation of the SS7 protocol. It provides implementation for Level 2 and above in the SS7 protocol Stack. Restcomm jSS7 Stack User Guide is included in the product documentation for Restcomm CAMEL Gateway . We suggest that you refer to this guide for more details on the underlying jSS7 Stack.

The diagram below depicts a high level design overview of Restcomm CAMEL Gateway .

camel application design overview

3.1. Geographic Redundancy

Restcomm CAMEL Gateway provides Load Balancing and Fault Tolerance. You can pair two or more third-party Application Servers to provide Fault-Tolerance in the Gateway and GSM Network level.

Geographic Redundancy can be achieved as shown in the diagram below:

MultipleGeoghraphicSite

3.2. Protocols Supported for Proxy

As of now, the Gateway supports the following protocols for proxy:

3.3. CAP Operations Supported

As of now, the Gateway supports the following protocols for proxy:

CAMEL phase 1 (full support except of activityTest operation)
  • initialDP

  • connect

  • releaseCall

  • requestReportBCSMEvent

  • eventReportBCSM

  • continue

CAMEL phase 2 (partial support)
  • connectToResource

  • furnishChargingInformation

  • applyCharging

  • applyChargingReport

  • promptAndCollectUserInformation

  • cancel

3.4. Multi tenancy support

Multi tenancy allows a single instance of Restcomm CAMEL Gateway to connect to different operators, with each connection having its own links and point-codes.

Restcomm CAMEL Gateway achieves Multi tenancy by splitting a model of SS7 network into several logical networks. Each logical network has a corresponding digital key called "networkId" with a default value of 0 (unless specified differently). For every "networkId", you can specify a corresponding HTTP Application to separate the business logic for each network.

If you would like to get more details about setting up Multi tenancy at jSS7, please refer to the Restcomm jSS7 Admin Guide.

The diagram below depicts the high level design for Multi tenancy support in Restcomm CAMEL Gateway .

camel application design overview multitenancy

4. Running

4.1. Running the Gateway

Procedure: Run Restcomm CAMEL Gateway
  1. Pre-requisite:

    • You must have Restcomm CAMEL Gateway installed as explained in the Installation Guide.

  2. In order to start the Gateway, you must start the JBoss Application Server. Execute the run.sh (Unix) or run.bat (Microsoft Windows) startup script in the restcomm-camel-7.1.0-SNAPSHOT/jboss-5.1.0.GA/bin folder (on Unix or Windows). Note that this will start the server in the default profile. The "default" profile is a clean profile, which entails configuring the entire SS7 Stack and CAMEL Gateway.

  3. Result: If the service started properly you should see the following last few output lines in the Unix terminal or Command Prompt depending on your environment:

    03:09:15,957 INFO  [SccpResourceImpl] (main) Started Sccp Resource
    03:09:15,958 INFO  [SccpStackImpl-SccpStack] (main) Starting routing engine...
    03:09:15,958 INFO  [SccpStackImpl-SccpStack] (main) Starting management ...
    03:09:15,958 INFO  [SccpStackImpl-SccpStack] (main) Starting MSU handler...
    03:09:15,982 INFO  [TCAPStackImpl] (main) Starting ...org.mobicents.protocols.ss7.tcap.TCAPProviderImpl@3e3fc7f9
    03:09:15,982 INFO  [TCAPProviderImpl] (main) Starting TCAP Provider
    03:09:15,982 INFO  [TCAPProviderImpl] (main) Registered SCCP listener with address 146
    03:09:16,215 INFO  [SS7Service] (main)  [[[[[[[[[ Restcomm Camel 3.0.0-SNAPSHOT service started ]]]]]]]]]
    03:09:16,222 INFO  [CamelPropertiesManagement] (main) Loading CAMEL Properties from /home/abhayani/workarea/mobicents/telestax/binary/CAMEL/restcomm-slee-6.1.1.GA/jboss-5.1.0.GA/server/default/data/CamelManagement_camelproperties.xml
    03:09:16,223 INFO  [CamelManagement] (main) Started CamelGatewayManagement
    03:09:16,231 INFO  [ShellServer] (main) Starting SS7 management shell environment
    03:09:16,237 INFO  [ShellServer] (main) ShellExecutor listening at /127.0.0.1:3435
    ........
    ........
    03:09:21,830 INFO  [DeploymentMBeanImpl] (pool-24-thread-1) Installed ResourceAdaptorID[name=CAPResourceAdaptor,vendor=org.mobicents,version=2.0]
    03:09:21,831 INFO  [DeploymentMBeanImpl] (pool-24-thread-1) Installed DeployableUnitID[url=file:/home/abhayani/workarea/mobicents/telestax/binary/CAMEL/restcomm-slee-6.1.1.GA/jboss-5.1.0.GA/server/default/deploy/mobicents-slee-ra-cap-du-2.8.0-SNAPSHOT.jar/]
    03:09:22,105 INFO  [CAPResourceAdaptor] (pool-24-thread-1) Verifying configuring CAP RA: CAPRA
    03:09:22,106 INFO  [CAPResourceAdaptor] (pool-24-thread-1) Configuring CAP RA: CAPRA
    03:09:22,106 INFO  [ResourceManagement] (pool-24-thread-1) Created Resource Adaptor Entity CAPRA for ResourceAdaptorID[name=CAPResourceAdaptor,vendor=org.mobicents,version=2.0] Config Properties: [(capJndi:java.lang.String=java:/mobicents/ss7/cap),(timeout:java.lang.Integer=0)]
    03:09:22,356 INFO  [ResourceManagement] (pool-24-thread-1) Activated RA Entity CAPRA
    03:09:22,607 INFO  [ResourceManagement] (pool-24-thread-1) Bound link between RA Entity CAPRA and Name CAPRA
    03:09:22,858 INFO  [DeploymentMBeanImpl] (pool-24-thread-1) Installing DeployableUnitID[url=file:/home/abhayani/workarea/mobicents/telestax/binary/CAMEL/restcomm-slee-6.1.1.GA/jboss-5.1.0.GA/server/default/deploy/services-DU-3.0.0-SNAPSHOT.jar/]
    03:09:23,048 INFO  [DeploymentMBeanImpl] (pool-24-thread-1) Installed LibraryID[name=library-camelgateway,vendor=org.mobicents,version=2.0]
    03:09:23,079 INFO  [DeploymentMBeanImpl] (pool-24-thread-1) Installed SbbID[name=CamelGatewaySbb,vendor=org.mobicents,version=1.0]
    03:09:23,094 INFO  [DeploymentMBeanImpl] (pool-24-thread-1) Installed ServiceID[name=mobicents-camelgateway,vendor=org.mobicents,version=1.0]. Root sbb is SbbID[name=CamelGatewaySbb,vendor=org.mobicents,version=1.0]
    03:09:23,095 INFO  [DeploymentMBeanImpl] (pool-24-thread-1) Installed DeployableUnitID[url=file:/home/abhayani/workarea/mobicents/telestax/binary/CAMEL/restcomm-slee-6.1.1.GA/jboss-5.1.0.GA/server/default/deploy/services-DU-3.0.0-SNAPSHOT.jar/]
    03:09:23,352 INFO  [ServiceManagementImpl] (pool-24-thread-1) Activated ServiceID[name=mobicents-camelgateway,vendor=org.mobicents,version=1.0]
    03:09:23,605 INFO  [MobicentsCache] (main) Starting JBoss Cache...
    03:09:23,631 INFO  [ComponentRegistry] (main) JBoss Cache version: JBossCache 'Cascabel' 3.1.0.GA
    03:09:23,631 INFO  [MobicentsCache] (main) Mobicents Cache started, status: STARTED, Mode: LOCAL
    03:09:23,648 INFO  [SleeManagementMBean] (main)  ## ## ## ## ## ## ## Restcomm JAIN SLEE 3.0.0-SNAPSHOT "Adam" started ## ## ## ## ## ## ##
    03:09:23,762 INFO  [HttpClientResourceAdaptor] (main) HttpClientResourceAdaptor=HttpClientResourceAdaptor entity activated.
    03:09:23,766 INFO  [CAPResourceAdaptor] (main) Successfully connected to CAP service[java:/mobicents/ss7/cap]
    03:09:24,873 INFO  [Http11Protocol] (main) Starting Coyote HTTP/1.1 on http-127.0.0.1-8080
    03:09:24,887 INFO  [AjpProtocol] (main) Starting Coyote AJP/1.3 on ajp-127.0.0.1-8009
    03:09:24,893 INFO  [ServerImpl] (main) JBoss (Microcontainer) [5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634)] Started in 58s:831ms
  4. You need to use the Shell Client to connect to Restcomm CAMEL Gateway and configure the SS7 Stack and CAMEL Gateway routing rule.

If you are starting Restcomm CAMEL Gateway for the first time, you must configure SS7.

Once configured, the state, the configuration of SS7 and CAMEL is persisted. This means that your configuration will still be available even after restarting the server. The next chapter will provide more details about configuring SS7 and the CAMEL Gateway.

Procedure: Stop the Gateway
  1. To stop the Restcomm CAMEL Gateway , you must shut down the JBoss Application Server. To shut down the server(s) you must execute the shutdown.sh -s (Unix) or shutdown.bat -s (Microsoft Windows) script in the restcomm-camel-7.1.0-SNAPSHOT/jboss-5.1.0.GA/bin directory (on Unix or Windows).

  2. If the server stopped properly, you will see the following three lines as the last output in the Unix terminal or Command Prompt:

[Server] Shutdown complete
Halting VM

4.2. Running the Gateway - Simulator Profile

The Restcomm CAMEL Gateway offers you an option to run the Gateway with a "simulator" profile for testing purpose. The "simulator" profile is a pre-configured profile to work with the jss7-simulator. Starting the Gateway with the "simulator" profile is similar to the steps explained for the "default" profile except that you must pass the string value "simulator" to the -c command line option when invoking the run script.

[bin]$ ./run.sh -c simulator

4.3. Running the Shell

Before you execute commands to configure the Gateway, you must start the Shell client and connect to the managed instance. The shell terminal can be started by issuing the following command from restcomm-camel-7.1.0-SNAPSHOT/jboss-5.1.0.GA/bin directory:

[$] ./ss7-cli.sh

Once console starts, it will print the following information and await further commands:

version=2.0.0-SNAPSHOT,name=restcomm CLI,prefix=mobicents,vendor=TeleStax
restcomm>

Executing further commands requires that you connect to a managed instance. For more details on connecting to an instance; for a list of all supported commands and details on configuring the SS7 stack, refer to the Restcomm SS7 Stack User Guide.

5. Configuring

Now that you have set up the Gateway you must configure it to suit your requirements. Restcomm CAMEL Gateway comes with an easy to use CLI (Shell) to allow easy configuration and management. This chapter will help you configure the Restcomm CAMEL Gateway .

5.1. Configuring the SS7 Stack

You must configure the SS7 stack prior to configuring CAMEL Gateway. For details on configuring the SS7 Stack please refer to the Restcomm SS7 Stack User Guide. You must first start the Shell as explained in the previous chapter and connect to the managed instance prior to configuring the Stack. The Restcomm SS7 Stack User Guide lists all available Shell commands to configure SS7. In addition, help files are available all the commands provided.

5.2. Configuring CAMEL Gateway

You must configure Routing Rule for the Gateway to forward all incoming CAP operations to third party application over HTTP. You can do this by using the camel set route command to forward all request to same URL irrespective of networkId (multi tenancy).

For multi tenancy use command camel networkrule create for each networkId. If for any given network, there is no rule defined, Restcomm CAMEL Gateway will use the default defined by camel set route

5.2.1. Create new Routing Rule

Command

camel set route

SYNOPSIS

camel set route <url>

DESCRIPTION

This command is used to create a new routing rule for camel gateway.

EXAMPLES
camel set route http://localhost:8080/camegatewaydemo/test

The above command will create routing rule in the CAMEL Gateway to forward all incoming CAP operations to third party application (if multi tenancy is not used or for networkId for which no networkrule is created).

5.2.2. View CAMEL Routing Rules

Command

camel get route

SYNOPSIS

camel get route

DESCRIPTION

This command is used to view details of configured routing rules in the CAMEL Gateway.

EXAMPLES
camel get route

route = http://localhost:8080/camegatewaydemo/test

5.2.3. Create new Routing Rule for multi tenancy

Command

camel networkrule create

SYNOPSIS

camel networkrule create <network-id> <url>

DESCRIPTION

This command is used to create a new routing rule for a network id.

EXAMPLES
	camel networkrule create 0 http://localhost:8080/camel

The above command will create a new network rule in the CAMEL Gateway for the network id 0. When the CAMEL Gw detects incoming CAP message from network id 0, gateway will direct the HTTP POST request to the URL http://localhost:8080/camel as specified by the routing rule.

SEE ALSO

camel networkrule, camel networkrule delete, camel networkrule show

5.2.4. Delete Routing Rule for multi tenancy

Command

camel networkrule delete

SYNOPSIS

camel networkrule delete <network-id>

DESCRIPTION

This command is used to delete an existing routing rule for a network id.

EXAMPLES
	camel networkrule delete 0

The above command will delete the network routing rule in the CAMEL Gateway for the network id 0

SEE ALSO

camel networkrule, camel networkrule create, camel networkrule show

5.2.5. Show Routing Rule for multi tenancy

Command

camel networkrule show

SYNOPSIS

camel networkrule show

DESCRIPTION

This command is used to view the details of all configured network routing rules in the CAMEL Gateway.

SEE ALSO

camel networkrule, camel networkrule create, camel networkrule delete

5.2.6. Set No Activity Timeout for Dialog

Command

camel set noactivitytimeout

SYNOPSIS

camel set noactivitytimeout <timeout-sec>

DESCRIPTION

Once TCAP dialog is established, if there is no activity for 'x' seconds, it will timeout. 'x' is configurable, please see tcap set dialogidletimeout command. However in case of Camel Applications, the dialog can live much longer (for example call). Camel gateway will keep renewing the TCAP dialog automatically, however if peer side is faulty or application didn’t send proper response to end TCAP dialog, there will be leak and dialog will remain alive forever. To avoid such situations set the noactivitytimeout in seconds such that if there is no activity in dialog for 'noactivitytimeout' sec, Camel gateway will call application indicating same. Application may take corrective action like End TCAP dialog or send empty response back in which case TCAP dialog continues and Camel gateway again makes call to application after 'noactivitytimeout'

PARAMETERS

Standard Parameters

timeout-sec		-	timeout in seconds after which application must
					be called if there is no activity in TCAP dialog.
					Default value is 3600 seconds (1 hour).
SEE ALSO

camel get noactivitytimeout

5.2.7. Get No Activity Timeout for Dialog

Command

camel get noactivitytimeout

SYNOPSIS

camel set noactivitytimeout

DESCRIPTION

Returns the noactivitytimeout value. Once TCAP dialog is established, if there is no activity for 'x' seconds, it will timeout. 'x' is configurable, please see tcap set dialogidletimeout command. However in case of Camel Applications, the dialog can live much longer (for example call). Camel gateway will keep renewing the TCAP dialog automatically, however if peer side is faulty or application didn’t send proper response to end TCAP dialog, there will be leak and dialog will remain alive forever. To avoid such situations set the noactivitytimeout in seconds such that if there is no activity in dialog for 'noactivitytimeout' sec, Camel gateway will call application indicating same. Application may take corrective action like End TCAP dialog or send empty response back in which case TCAP dialog continues and Camel gateway again makes call to application after 'noactivitytimeout'

PARAMETERS
SEE ALSO

camel set noactivitytimeout

5.2.8. Set Update Assigned Invoke Ids

Command

camel set updateassignedinvokeids

SYNOPSIS

camel set updateassignedinvokeids <true | false>

DESCRIPTION

Once Application sends back HTTP response carrying CAP messages as XML payload to be sent to peer, Camel gateway will send these invokes to peer and assign InvokeId generated by Camel gateway. HTTP Application wouldn’t be aware of which invoke id belongs to which CAP message and hence if there are some error’s reported by peer (carrying invoke id), HTTP application wouldn’t know this error is for which invoke? To avoid such situation set the updateAssignedInvokeIds to true so Camel gateway will send back HTTP request carrying all the assigned invokeId’s as soon as it sends Invoke to peer

PARAMETERS

Standard Parameters

true | false		-	If set to true, camel gateway will send the HTTP
					request carrying assigned id's as explained above
SEE ALSO

camel get updateassignedinvokeids

5.2.9. Get Update Assigned Invoke Ids

Command

camel get updateassignedinvokeids

SYNOPSIS

camel get updateassignedinvokeids

DESCRIPTION

Returns the value of updateassignedinvokeids

PARAMETERS

Standard Parameters

SEE ALSO

camel set updateassignedinvokeids

6. HTTP Transfer Mechanism

CAMEL Gateway supports implementation of HTTP 1.1 standards and acts as a HTTP Client invoking (HTTP POST) the HTTP Application deployed on the third-party Application Server. The HTTP Request carries XML payload with CAP specific information.

The HTTP callback mechanism allows third-party applications to be developed independently of Operating System, Programming Language and Framework. The third-party application can be either of the following technologies on any Operating System:

  • Apache Tomcat, JBoss AS, Oracle Application Server, IBM Websphere etc for JSP/Servlet on Java

  • PHP

  • Microsoft IIS for ASP

HTTP errors are supported and recognized by the CAMEL Gateway .

6.1. HTTP Message Structure

The diagram below depicts an example message sequence for interacting with CAMEL Gateway HTTP API.

http call flow

6.1.1. HTTP payload for INITIAL_DP_REQUEST

When the Gateway receives the 'INITIAL_DP_REQUEST' request, CAMEL Gateway will send an XML Payload to the third-party Application. The XML structure will be as below:

<?xml version="1.0" encoding="UTF-8" ?>
<dialog type="Begin" appCntx="CapV2_gsmSSF_to_gsmSCF" localId="1" remoteId="1504012"
	 capMessagesSize="1" returnMessageOnError="false">
	<origAddress pc="2" ssn="146">
		<ai value="83"/>
		<gt type="GlobalTitle0100" tt="0" es="1" np="1" nai="4" digits="2222201"/>
	</origAddress>
	<destAddress pc="0" ssn="8">
		<ai value="18"/>
		<gt type="GlobalTitle0100" tt="0" es="1" np="1" nai="4" digits="1111112"/>
	</destAddress>
	<initialDP_Request invokeId="1" isCAPVersion3orLater="false">
		<serviceKey value="14"/>
		<calledPartyNumber>
			<isupCalledPartyNumber address="0782512817" natureOfAddresIndicator="3"
				numberingPlanIndicator="1" internalNetworkNumberIndicator="0"/>
		</calledPartyNumber>
		<callingPartyNumber>
			<isupCallingPartyNumber address="93781202040" natureOfAddresIndicator="4"
				numberingPlanIndicator="1" numberIncompleteIndicator="0"
				addressRepresentationRestrictedIndicator="0" screeningIndicator="3"/>
		</callingPartyNumber>
		<callingPartysCategory>
			<isupCallingPartysCategory callingPartyCategory="10"/>
		</callingPartysCategory>
		<ipsspCapabilities/>
		<locationNumber>
			<isupLocationNumber address="937802" natureOfAddresIndicator="4"
				numberingPlanIndicator="1" internalNetworkNumberIndicator="0"
				addressRepresentationRestrictedIndicator="0" screeningIndicator="3"/>
		</locationNumber>
		<additionalCallingPartyNumber>
			<genericNumber address="93781202040" natureOfAddresIndicator="4"
				numberingPlanIndicator="1" numberIncomplete="false"
				addressRepresentationRestrictedIndicator="0" screeningIndicator="3"
				numberQualifierIndicator="6"/>
		</additionalCallingPartyNumber>
		<bearerCapability>
			<bearerCap>
				<userServiceInformation codingStandart="0" informationTransferCapability="0"
					transferMode="0" informationTransferRate="16" l1UserInformation="3"
					syncMode="0" negotiation="0" userRate="0" intermediateRate="0" nicOnTx="0"
					 nicOnRx="0" fcOnTx="0" fcOnRx="0" hdr="0" multiframe="0" mode="0" lli="0"
					 assignor="0" inBandNegotiation="0" stopBits="0" dataBits="0" parity="0"
					 duplexMode="0" modemType="0"/>
			</bearerCap>
		</bearerCapability>
		<eventTypeBCSM value="termAttemptAuthorized"/>
		<imsi number="412500208832015"/>
		<subscriberState subscriberStateChoice="assumedIdle"/>
		<extBasicServiceCode>
			<extTeleservice>
				<teleserviceCodeValue value="17"/>
			</extTeleservice>
		</extBasicServiceCode>
		<callReferenceNumber>
			<data value="1605321A0155F2B2"/>
		</callReferenceNumber>
		<mscAddress number="93781090001" nai="international_number" npi="ISDN"/>
		<timeAndTimezone year="2013" month="4" day="17" hour="12" minute="31"
			second="36" timeZone="18"/>
	</initialDP_Request>
</dialog>

The XML structure is similar to actual SS7 CAP messages. The <dialog> tag acts as a parent tag.

The XML element <dialog> contains various attributes to represent the state and the parameters of the Dialog. This section explains in detail all possible attributes and what they represent.

type

This parameter specifies the type of TCAP message that has arrived at the CAMEL GW. The possible values for 'type' are: Begin, End, Continue, Abort or Unknown.. The initial message that comes from a CAMEL peer is Begin, The final message can be End (normal Dialog end) or Abort (abnormal Dialog end). Continue messages are used for message transfer without closing of Dialog.

appCntx

Represents the CAP Dialog Application Context. Possible values are.

  • CAP V1: CapV1_gsmSSF_to_gsmSCF

  • CAP V2: CapV2_gsmSSF_to_gsmSCF, CapV2_gsmSRF_to_gsmSCF

  • CAP V3: CapV3_gsmSSF_scfGeneric, CapV3_gsmSSF_scfAssistHandoff, CapV3_gsmSRF_gsmSCF, CapV3_gprsSSF_gsmSCF, CapV3_gsmSCF_gprsSSF, CapV3_cap3_sms

  • CAP V4: CapV4_gsmSSF_scfGeneric, CapV4_gsmSSF_scfAssistHandoff, CapV4_scf_gsmSSFGeneric, CapV4_gsmSRF_gsmSCF, CapV4_cap4_sms

networkId

netwrokId is used for multi-tenancy support. Restcomm CAMEL Gateway can connect to multiple operators each differentiated by a networkId. The default value is 0. When a message reaches the Gateway, the SCCP Stack assigns a networkId. (For more details, please refer to the jSS7 Stack User Guide). The Gateway can route messages to different applications depending on the configured networkId routing rule.

capMessagesSize

Represents the actual number of CAP messages carried in this XML Payload. This value can be 0 if no CAP messages are carried or 1 or more for multiple CAP messages. This is a mandatory parameter.

origAddress and destAddress

SCCP Addresses representing the CallingPartyAddress and CalledPartyAddress.

This is followed by the actual CAP message of the dialog.

All message types have a mandatory invokeId attribute helping to relate the response to the request.

6.1.2. Payloads for requests / responses from third-party Application

When a third-party Application receives a HTTP Request with an initial XML Payload, it must reply by sending a HTTP Response with an XML Payload to the gateway. This payload will specify whether the gateway should end or continue the dialog. It will also specify what other CAP components (Invokes, ReturnResult or Error message) will be sent to a peer. The description below will help you to understand these payloads.

  • Empty message: Application can respond back to the Gateway such that it sends an empty TC-CONTINUE message to a peer, without ending the Dialog. The Application needs to provide "capMessagesSize="0" attribute for <dialog> to specify that no CAP Invokes / Return response needs to be sent.

<?xml version="1.0" encoding="UTF-8" ?>
	<dialog capMessagesSize="0">
</dialog>
  • Empty TC-CONTINUE message (without CAP requests or error messages) will be sent only at a dialog intiating state. If a dialog is already set and no CAP requests or error messages in HTTP payload then CAMEL GW will not send an empty TC-CONTINUE message to a peer. If you do need to send an empty TC-CONTINUE in a dialog set step you need to add sendEmptyContinue="true" attribute

<?xml version="1.0" encoding="UTF-8" ?>
	<dialog capMessagesSize="0" sendEmptyContinue="true">
</dialog>
  • Empty message that will end the CAP Dialog: To end the dialog, the application needs to add a parameter prearrangedEnd="false". The Gateway will send an empty TC-END and close the Dialog.

<?xml version="1.0" encoding="UTF-8" ?>
	<dialog capMessagesSize="0" prearrangedEnd="false">
</dialog>
  • Sending CAP Invokes / ReturnResult components: Below is an example with two Invokes that will be sent to a peer (without ending the CAP Dialog). The Application needs to specify the parameter capMessagesSize to the count of operations to send. In this payload, there are two components (Invokes) - continue_Request and releaseCall_Request. The templates for payload will be provided in the subsequent chapters.

<?xml version="1.0" encoding="UTF-8" ?>
<dialog capMessagesSize="2" invokeWithoutAnswerIds="1">
	<continue_Request/>
	<releaseCall_Request>
		<cause>
			<isupCauseIndicators location="4" causeValue="16" codingStandard="0" recommendation="0"/>
		</cause>
	</releaseCall_Request>
</dialog>

It is required to include the invokeId parameter in the payload, if the application is sending a ReturnResult component. The value of invokeId should be same as that received from the original Invoke request.

It is not required to include the invokeId parameter in the payload, if the application is sending a new Invoke component. The Gateway will automatically assign invokeId values to Invoke request sent by Application. The Application will get the assigned invokeId values from the next HTTP request sent by the CAMEL GW (The remark: this HTTP request will occur only when you configure "camel set updateassignedinvokeids" to true - Set Update Assigned Invoke Ids). This request will contain assignedInvokeIds parameter with assigned invokeId values (with comma separator) for sent Invoke components, in the order they have been sent. Below is an example of such a request from the Gateway.

<?xml version="1.0" encoding="UTF-8" ?>
<dialog type="Begin" appCntx="CapV4_gsmSSF_scfGeneric" networkId="11" localId="1"
	remoteId="1" assignedInvokeIds="1,2" capMessagesSize="0" returnMessageOnError="false">
	<origAddress pc="2" ssn="146">
		<ai value="83"/>
		<gt type="GlobalTitle0100" tt="0" es="1" np="1" nai="4" digits="2222201"/>
	</origAddress>
	<destAddress pc="0" ssn="8">
		<ai value="18"/>
		<gt type="GlobalTitle0100" tt="0" es="1" np="1" nai="4" digits="1111112"/>
	</destAddress>
</dialog>
  • Sending CAP Error components: Below is an example showing how to send CAP Error components for Invokes received by the Application from the Gateway. It is mandatory to include the invokeId parameter.

<?xml version="1.0" encoding="UTF-8" ?>
<dialog capMessagesSize="0" invokeWithoutAnswerIds="1">
	<errComponents>
		<invokeId value="1"/>
		<errorComponent type="CAPErrorMessageSystemFailure" errorCode="11">
			<unavailableNetworkResource value="endUserFailure"/>
		</errorComponent>
		<invokeId value="2"/>
		<errorComponent type="CAPErrorMessageParameterless" errorCode="4"/>
	</errComponents>
</dialog>
  • Aborting Dialog : The Application can abort a dialog and the Gateway will send a TC-ABORT message to peer as shown in the example below.

<?xml version="1.0" encoding="UTF-8" ?>
	<dialog capMessagesSize="0" capUserAbortReason="application_timer_expired">
	</dialog>

In this case, capUserAbortReason can be no_reason_given, application_timer_expired, not_allowed_procedures, abnormal_processing, congestion, invalid_reference, missing_reference or overlapping_dialogue.

  • invokeWithoutAnswerIds: When a third party application receives CAP Invoke components, it must decide how to respond to these Invoke components. For certain Invokes, ReturnResults are needed, for some others it is needed to send Error components as a response. In this case the CAP application should add components into a payload.

    For most cases, no responses are needed. In such cases, the third party application should inform the Gateway that it will not respond to Invoke components (with a list of invokeIds as comma separated values). This can be achieved using the parameter invokeWithoutAnswerIds.

    The example below shows the template for two such Invoke components with invokeId values 1 and 2.

<?xml version="1.0" encoding="UTF-8" ?>
<dialog capMessagesSize="1" invokeWithoutAnswerIds="1,2">
	<continue_Request/>
	<releaseCall_Request>
	</releaseCall_Request>
</dialog>
6.1.2.1. HTTP payload for CONTINUE_REQUEST

In order to send a CONTINUE_REQUEST to the Gateway, the third party Application must provide the below XML Payload.

	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		...
		<continue_Request/>
		...
	</dialog>
6.1.2.2. HTTP payload for CONNECT_REQUEST

In order to send a CONNECT_REQUEST to the Gateway, the third party Application must provide the below XML Payload.

	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ....>
		....
		<connect_Request>
			<destinationRoutingAddress>
				<calledPartyNumberList>
					<calledPartyNumber>
						<isupCalledPartyNumber address="923335340951" natureOfAddresIndicator="2"
							numberingPlanIndicator="1" internalNetworkNumberIndicator="0" />
					</calledPartyNumber>
				</calledPartyNumberList>
			</destinationRoutingAddress>
		</connect_Request>
	</dialog>

XML Payload for full CONNECT_REQUEST is as below:

	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ....>
		....
		<connect_Request>
			<destinationRoutingAddress>
			<calledPartyNumberList>
				<calledPartyNumber>
					<isupCalledPartyNumber address="111111111111" natureOfAddresIndicator="2"
						numberingPlanIndicator="1" internalNetworkNumberIndicator="0" />
				</calledPartyNumber>
			</calledPartyNumberList>
			</destinationRoutingAddress>
			<alertingPattern>
				<alertingPattern alertingCategory="Category5"/>
			</alertingPattern>
			<originalCalledPartyID>
				<isupOriginalCalledNumber address="7010900" natureOfAddresIndicator="3"
					numberingPlanIndicator="1" addressRepresentationRestrictedIndicator="1"/>
			</originalCalledPartyID>
			<carrier data="0B0C0D0E"/>
			<callingPartysCategory>
				<isupCallingPartysCategory callingPartyCategory="10"/>
			</callingPartysCategory>
			<redirectingPartyID>
				<isupRedirectingNumber address="7010900" natureOfAddresIndicator="3"
					numberingPlanIndicator="1" addressRepresentationRestrictedIndicator="1"/>
			</redirectingPartyID>
			<redirectionInformation>
				<isupRedirectionInformation redirectingIndicator="3"
					originalRedirectionReason="0" redirectionCounter="1" redirectionReason="6"/>
			</redirectionInformation>
			<genericNumbersList>
				<genericNumber>
					<genericNumber address="40" natureOfAddresIndicator="2" numberingPlanIndicator="0"
						numberIncomplete="false" addressRepresentationRestrictedIndicator="0"
						screeningIndicator="3" numberQualifierIndicator="1"/>
				</genericNumber>
			</genericNumbersList>
			<serviceInteractionIndicatorsTwo>
				<nonCUGCall value="false"/>
				<forwardServiceInteractionInd>
					<conferenceTreatmentIndicator value="rejectConferenceRequest"/>
				</forwardServiceInteractionInd>
			</serviceInteractionIndicatorsTwo>
			<chargeNumber>
				<isupLocationNumber address="0000077777" natureOfAddresIndicator="4"
					numberingPlanIndicator="0" internalNetworkNumberIndicator="0"
					addressRepresentationRestrictedIndicator="0" screeningIndicator="0"/>
			</chargeNumber>
			<legToBeConnected sendingSideID="leg5"/>
			<cugInterlock data="15161718"/>
			<cugOutgoingAccess value="true"/>
			<suppressionOfAnnouncement value="true"/>
			<OCSIApplicable value="true"/>
			<NAOliInfo value="40"/>
			<borInterrogationRequested value="true"/>
		</connect_Request>
	</dialog>
6.1.2.3. HTTP payload for RELEASE_CALL_REQUEST

In order to send a RELEASE_CALL_REQUEST to the Gateway, the third party Application must provide the below XML Payload.

	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		....
		<releaseCall_Request>
			<cause>
				<isupCauseIndicators location="4" causeValue="16" codingStandard="0"
					recommendation="0"/>
			</cause>
		</releaseCall_Request>
	</dialog>
6.1.2.4. HTTP payload for REQUEST_REPORT_BCSM_EVENT_REQUEST

In order to send a REQUEST_REPORT_BCSM_EVENT_REQUEST to the Gateway, the third party Application must provide the below XML Payload.

	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		....
		<requestReportBCSMEvent_Request>
			<bcsmEventList>
				<bcsmEvent>
					<eventTypeBCSM value="routeSelectFailure"/>
					<monitorMode value="interrupted"/>
					<legID sendingSideID="leg2"/>
				</bcsmEvent>
				<bcsmEvent>
					<eventTypeBCSM value="oCalledPartyBusy"/>
					<monitorMode value="interrupted"/>
					<legID sendingSideID="leg2"/>
				</bcsmEvent>
				<bcsmEvent>
					<eventTypeBCSM value="oNoAnswer"/>
					<monitorMode value="interrupted"/>
					<legID sendingSideID="leg2"/>
				</bcsmEvent>
				<bcsmEvent>
					<eventTypeBCSM value="oAnswer"/>
					<monitorMode value="notifyAndContinue"/>
					<legID sendingSideID="leg2"/>
				</bcsmEvent>
				<bcsmEvent>
					<eventTypeBCSM value="oDisconnect"/>
					<monitorMode value="interrupted"/>
					<legID sendingSideID="leg1"/>
				</bcsmEvent>
				<bcsmEvent>
					<eventTypeBCSM value="oDisconnect"/>
					<monitorMode value="interrupted"/>
					<legID sendingSideID="leg2"/>
				</bcsmEvent>
				<bcsmEvent>
					<eventTypeBCSM value="oAbandon"/>
					<monitorMode value="notifyAndContinue"/>
					<legID sendingSideID="leg1"/>
				</bcsmEvent>
			</bcsmEventList>
		</requestReportBCSMEvent_Request>
	</dialog>
6.1.2.5. HTTP payload for APPLY_CHARGING_REQUEST

In order to send a APPLY_CHARGING_REQUEST to the Gateway, the third party Application must provide the below XML Payload.

	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		....
		<applyCharging_Request>
			<aChBillingChargingCharacteristics>
				<maxCallPeriodDuration value="36000"/>
				<releaseIfdurationExceeded value="false"/>
			</aChBillingChargingCharacteristics>
			<partyToCharge>
				<sendingSideID value="1"/>
			</partyToCharge>
			<aChChargingAddress>
				<srfConnection value="10"/>
			</aChChargingAddress>
		</applyCharging_Request>
	</dialog>
6.1.2.6. HTTP payload for CANCEL_REQUEST

In order to send a CANCEL_REQUEST to the Gateway, the third party Application must provide the below XML Payload. All 3 possible CANCEL_REQUEST formats are presented below.

	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		....
		<cancel_Request>
			<invokeID value="11000"/>
		</cancel_Request>
		<cancel_Request>
			<callSegmentToCancel>
				<callSegmentID value="20"/>
			</callSegmentToCancel>
		</cancel_Request>
		<cancel_Request>
			<allRequests value="true"/>
		</cancel_Request>
	</dialog>

6.1.3. Payloads for requests / responses to the third-party Application

The CAMEL Gateway can send payloads other than INITIAL_DP_REQUEST to the third-party application as shown in the below examples.

Payload that contains CAP Error and Reject components from a peer
<?xml version="1.0" encoding="UTF-8" ?>
<dialog type="Continue" appCntx="CapV4_gsmSSF_scfGeneric" networkId="11"
	localId="12" remoteId="13" assignedInvokeIds="1" capMessagesSize="0"
	returnMessageOnError="false">
	<origAddress pc="2" ssn="146">
		<ai value="83"/>
		<gt type="GlobalTitle0100" tt="0" es="1" np="1" nai="4" digits="2222201"/>
	</origAddress>
	<destAddress pc="0" ssn="8">
		<ai value="18"/>
		<gt type="GlobalTitle0100" tt="0" es="1" np="1" nai="4" digits="1111112"/>
	</destAddress>
	<errComponents>
		<invokeId value="1"/>
		<errorComponent type="CAPErrorMessageSystemFailure" errorCode="11">
			<unavailableNetworkResource value="endUserFailure"/>
		</errorComponent>
		<invokeId value="2"/>
		<errorComponent type="CAPErrorMessageParameterless" errorCode="4"/>
		</errComponents>
	<rejectComponents>
		<invokeId value="1"/>
		<rejectComponent problemType="ReturnError">
			<problemReturnError value="UnrecognizedInvokeID"/>
		</rejectComponent>
	</rejectComponents>
</dialog>
TC-USER-ABORT message from a peer that breaks the CAP Dialog
<?xml version="1.0" encoding="UTF-8" ?>
<dialog type="Abort" appCntx="CapV4_gsmSSF_scfGeneric" networkId="11" localId="1"
	remoteId="1" capMessagesSize="0" capUserAbortReason="application_timer_expired"
	returnMessageOnError="false">
	<origAddress pc="2" ssn="146">
		<ai value="83"/>
		<gt type="GlobalTitle0100" tt="0" es="1" np="1" nai="4" digits="2222201"/>
	</origAddress>
	<destAddress pc="0" ssn="8">
		<ai value="18"/>
		<gt type="GlobalTitle0100" tt="0" es="1" np="1" nai="4" digits="1111112"/>
	</destAddress>
</dialog>

Templates for CAP primitives that can come from a SS7 peer are covered in the subsequent sections of this document.

6.1.3.1. Payload for INITIAL_DP_REQUEST Invoke from a SS7 peer

INITIAL_DP_REQUEST is a complicated operation. The templates below describe 3 possible payloads for this operation.

	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		...
		<initialDP_Request invokeId="24" isCAPVersion3orLater="false">
			<serviceKey value="110"/>
			<calledPartyNumber>
				<isupCalledPartyNumber address="12270109000" natureOfAddresIndicator="3"
					numberingPlanIndicator="1" internalNetworkNumberIndicator="1"/>
			</calledPartyNumber>
			<callingPartyNumber>
				<isupCallingPartyNumber address="75" natureOfAddresIndicator="3"
					numberingPlanIndicator="1" numberIncompleteIndicator="1"
					addressRepresentationRestrictedIndicator="1" screeningIndicator="3"/>
			</callingPartyNumber>
			<callingPartysCategory>
				<isupCallingPartysCategory callingPartyCategory="10"/>
			</callingPartysCategory>
			<cgEncountered value="manualCGencountered"/>
			<ipsspCapabilities ipRoutingAddressSupported="true" voiceBackSupported="true"
				generationOfVoiceAnnouncementsFromTextSupported="true"/>
			<locationNumber>
				<isupLocationNumber address="12345333111" natureOfAddresIndicator="3"
					numberingPlanIndicator="4" internalNetworkNumberIndicator="1"
					addressRepresentationRestrictedIndicator="0" screeningIndicator="1"/>
			</locationNumber>
			<originalCalledPartyID>
				<isupOriginalCalledNumber address="7010900" natureOfAddresIndicator="3"
					numberingPlanIndicator="1" addressRepresentationRestrictedIndicator="1"/>
			</originalCalledPartyID>
			<extensions>
				<extensionFieldList>
					<extensionField localCode="2" criticalityType="typeIgnore">
						<data value=""/>
					</extensionField>
					<extensionField localCode="3" criticalityType="typeAbort">
						<data value="FF"/>
					</extensionField>
				</extensionFieldList>
			</extensions>
			<highLayerCompatibility>
				<isupUserTeleserviceInformation codingStandard="2" interpretation="4"
					presentationMethod="1" highLayerCharIdentification="51"/>
			</highLayerCompatibility>
			<additionalCallingPartyNumber>
				<genericNumber address="12345" natureOfAddresIndicator="3"
					numberingPlanIndicator="4" numberIncomplete="true"
					addressRepresentationRestrictedIndicator="0" screeningIndicator="2"
					numberQualifierIndicator="5"/>
			</additionalCallingPartyNumber>
			<bearerCapability>
				<bearerCap>
					<userServiceInformation codingStandart="1" informationTransferCapability="24"
						transferMode="2" informationTransferRate="17"/>
				</bearerCap>
			</bearerCapability>
			<eventTypeBCSM value="collectedInfo"/>
			<redirectingPartyID>
				<isupRedirectingNumber address="7010900" natureOfAddresIndicator="3"
					numberingPlanIndicator="1" addressRepresentationRestrictedIndicator="1"/>
			</redirectingPartyID>
			<redirectionInformation>
				<isupRedirectionInformation redirectingIndicator="3" originalRedirectionReason="0"
					redirectionCounter="1" redirectionReason="6"/>
			</redirectionInformation>
			<imsi number="607029900140199"/>
			<subscriberState subscriberStateChoice="notProvidedFromVLR"/>
			<locationInformation>
				<ageOfLocationInformation value="111"/>
			</locationInformation>
			<extBasicServiceCode>
				<extTeleservice teleserviceCodeValue="telephony"/>
			</extBasicServiceCode>
			<callReferenceNumber>
				<data value="13FA3D3DEA"/>
			</callReferenceNumber>
			<mscAddress number="2207750007" nai="international_number" npi="ISDN"/>
			<calledPartyBCDNumber number="41788005047" nai="international_number" npi="ISDN"/>
			<timeAndTimezone year="2005" month="11" day="24" hour="13" minute="10" second="56"
				timeZone="0"/>
			<callForwardingSSPending value="true"/>
			<initialDPArgExtension isCAPVersion3orLater="false">
				<gmscAddress number="2207750007" nai="international_number" npi="ISDN"/>
			</initialDPArgExtension>
		</initialDP_Request>
	</dialog>
	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		...
		<initialDP_Request invokeId="24" isCAPVersion3orLater="false">
			<serviceKey value="110"/>
			<calledPartyNumber>
				<isupCalledPartyNumber address="12270109000" natureOfAddresIndicator="3"
					numberingPlanIndicator="1" internalNetworkNumberIndicator="1"/>
			</calledPartyNumber>
		</initialDP_Request>
	</dialog>
	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		...
		<initialDP_Request invokeId="12" isCAPVersion3orLater="false">
			<serviceKey value="110"/>
			<calledPartyNumber>
				<isupCalledPartyNumber address="1111222266" natureOfAddresIndicator="4"
					numberingPlanIndicator="1" internalNetworkNumberIndicator="0"/>
			</calledPartyNumber>
			<cgEncountered value="scpOverload"/>
			<cause>
				<isupCauseIndicators location="4" causeValue="58" codingStandard="2"
					recommendation="0"/>
			</cause>
			<serviceInteractionIndicatorsTwo>
				<nonCUGCall value="false"/>
				<holdTreatmentIndicator value="rejectHoldRequest"/>
			</serviceInteractionIndicatorsTwo>
			<carrier data="01020304"/>
			<cugIndex>
				<value value="211"/>
			</cugIndex>
			<cugInterlock data="0B0C0D0E"/>
			<cugOutgoingAccess value="true"/>
		</initialDP_Request>
	</dialog>
6.1.3.2. Payload for EVENT_REPORT_BCSM_REQUEST Invoke from a SS7 peer
	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		...
		<eventReportBCSM_Request invokeId="24">
			<eventTypeBCSM value="routeSelectFailure"/>
			<eventSpecificInformationBCSM>
				<routeSelectFailureSpecificInfo>
					<causeCap>
						<isupCauseIndicators location="4" causeValue="16" codingStandard="0" recommendation="0"/>
					</causeCap>
				</routeSelectFailureSpecificInfo>
			</eventSpecificInformationBCSM>
			<legID>
				<receivingSideID value="2"/>
			</legID>
			<miscCallInfo>
				<messageType value="0"/>
			</miscCallInfo>
		</eventReportBCSM_Request>
	</dialog>
6.1.3.3. Payload for APPLY_CHARGING_REPORT_REQUEST Invoke from a SS7 peer
	<?xml version="1.0" encoding="UTF-8" ?>
	<dialog ...>
		...
		<applyChargingReport_Request invokeId="24">
			<timeDurationChargingResult>
			<partyToCharge>
				<receivingSideID value="1"/>
			</partyToCharge>
			<timeInformation>
				<timeIfNoTariffSwitch value="26"/>
			</timeInformation>
			</timeDurationChargingResult>
		</applyChargingReport_Request>
	</dialog>
6.1.3.4. Payload for PROMPT_AND_COLLECT_USER_INFORMATION_RESPONSE ReturnResultLast from a SS7 peer
	<promptAndCollectUserInformation_Response invokeId="21">
	<digitsResponse>
	<genericNumber address="987" natureOfAddresIndicator="1" numberingPlanIndicator="2" numberIncomplete="true"
	addressRepresentationRestrictedIndicator="3" screeningIndicator="0" numberQualifierIndicator="0"/>
	</digitsResponse>
	</promptAndCollectUserInformation_Response>
6.1.3.5. No Acivity Timeout Call

If there is no activity for noactivitytimeout period in seconds, &THIS.PLATFORM;will send <dialog> with attribute noActivityTimeOut set to true indicating there is no activity. Application can take necessary action, for example either end Dialog or send empty response for Dialog to continue.

	<?xml version="1.0" encoding="UTF-8" ?>
<dialog type="Continue" appCntx="CapV1_gsmSSF_to_gsmSCF" networkId="0" localId="1" remoteId="9"
	 capMessagesSize="0" noActivityTimeOut="true" returnMessageOnError="false">
...
</dialog>

7. XML Parser API

Restcomm CAMEL Gateway exposes easy to use Java framework to serialize and deserialize the CAP messages. If you are using Java Servlets for your business logic, this framework will make it very easy to compose your business logic. However, using this framework is not mandatory and you are free to create your own XML parser.

7.1. Maven dependency

If you are using maven to build your project, define following dependencies to use XML Framework in your project

		<dependency>
			<groupId>org.restcomm.camelgw</groupId>
			<artifactId>xml</artifactId>
			<version>7.1.0-SNAPSHOT</version>
		</dependency>
Note

Telestax maintains the archieve in sonatype repository. Please add the following in your pom’s repositories tag.

		<repository>
			<id>mobicents-public-repository-group</id>
			<name>Mobicens Public Maven Repository Group</name>
			<url>https://oss.sonatype.org/content/groups/public/</url>
			<layout>default</layout>
			<releases>
				<enabled>true</enabled>
				<updatePolicy>never</updatePolicy>
			</releases>
			<snapshots>
				<enabled>true</enabled>
				<updatePolicy>never</updatePolicy>
			</snapshots>
		</repository>

7.2. Simple example

Below is the simple HttpServlet example that received INITIAL_DP_REQUEST and responds CONTINUE_REQUEST The flow of message is same as shown in HTTP Message Structure.

package org.restcomm.applications.camelgw.examples.http;

public class TestServlet extends HttpServlet {

	private static final Logger logger = Logger.getLogger(TestServlet.class);

	private EventsSerializeFactory factory = null;

	@Override
	public void init() {
		factory = new EventsSerializeFactory();
	}

	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<body>");
		out.println("<h1>CAMEL Gw Demo Get</h1>");
		SccpAddress orgAddress = new SccpAddressImpl(RoutingIndicator.ROUTING_BASED_ON_DPC_AND_SSN, null, 1, 8);
		SccpAddress dstAddress = new SccpAddressImpl(RoutingIndicator.ROUTING_BASED_ON_DPC_AND_SSN, null, 2, 8);

		XmlCAPDialog copy = new XmlCAPDialog(CAPApplicationContext.CapV1_gsmSSF_to_gsmSCF, orgAddress, dstAddress, 12l,
				13l);

		try {
			byte[] data = factory.serialize(copy);
			System.out.println(Arrays.toString(data));
		} catch (XMLStreamException e) {
			e.printStackTrace();
		}

		out.println("</body>");
		out.println("</html>");
	}

	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
		ServletInputStream is = request.getInputStream();
		try {
			XmlCAPDialog original = factory.deserialize(is);
			HttpSession session = request.getSession(true);
			if (logger.isInfoEnabled()) {
				logger.info("doPost. HttpSession=" + session.getId() + " Dialog = " + original);
			}

			FastList<CAPMessage> capMessages = original.getCAPMessages();

			for (FastList.Node<CAPMessage> n = capMessages.head(), end = capMessages.tail(); (n = n.getNext()) != end;) {

				CAPMessage capMessage = n.getValue();
				switch (capMessage.getMessageType()) {
				case initialDP_Request:
					InitialDPRequestImpl initialDPRequest = (InitialDPRequestImpl) capMessage;
					this.handleIdp(original, initialDPRequest);
					break;
				case applyChargingReport_Request:
					ApplyChargingReportRequestImpl applyChargingReportRequest = (ApplyChargingReportRequestImpl) capMessage;
					logger.info(String.format("Received applyChargingReportRequest=%s", applyChargingReportRequest));
					break;
				case eventReportBCSM_Request:
					EventReportBCSMRequestImpl eventReportBCSMRequest = (EventReportBCSMRequestImpl) capMessage;
					logger.info(String.format("Received eventReportBCSMRequest=%s", eventReportBCSMRequest));
					break;
				default:
					logger.info(String.format("unrecognized capMessage=%s", capMessage));
					break;

				}
			}

			// send response
			this.sendResponse(response, original);
		} catch (XMLStreamException e) {
			logger.error("Error while processing received XML", e);
		}

	}

	private void sendResponse(HttpServletResponse response, XmlCAPDialog original) {
		byte[] data;
		try {
			data = factory.serialize(original);
			response.getOutputStream().write(data);
			response.flushBuffer();
		} catch (XMLStreamException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private void handleIdp(XmlCAPDialog original, InitialDPRequestImpl initialDPRequest) {
		try {
			logger.info(String.format("Received initialDPRequest=%s", initialDPRequest));

			// Lets send back CON and end Dialog
			original.getCAPMessages().clear();

			ContinueRequest cue = new ContinueRequestImpl();
			original.addCAPMessage(cue);

			original.close(false);
		} catch (CAPException e) {
			e.printStackTrace();
		}
	}
}

7.3. EventsSerializeFactory

This section provides the details for EventsSerializeFactory

package org.restcomm.camelgateway;

public class EventsSerializeFactory {

	private static final String DIALOG = "dialog";
	private static final String TYPE = "type";
	private static final String TAB = "\t";

	final XMLBinding binding = new XMLBinding();

	public EventsSerializeFactory() {
        // CAPErrorMessage classes
        binding.setAlias(CAPErrorMessageCancelFailedImpl.class, ErrorComponentCap.CAP_ERROR_MESSAGE_CANCEL_FAILED);
        binding.setAlias(CAPErrorMessageParameterlessImpl.class, ErrorComponentCap.CAP_ERROR_MESSAGE_PARAMETERLESS);
        binding.setAlias(CAPErrorMessageRequestedInfoErrorImpl.class, ErrorComponentCap.CAP_ERROR_MESSAGE_REQUESTED_INFO_ERROR);
        binding.setAlias(CAPErrorMessageSystemFailureImpl.class, ErrorComponentCap.CAP_ERROR_MESSAGE_SYSTEM_FAILURE);
        binding.setAlias(CAPErrorMessageTaskRefusedImpl.class, ErrorComponentCap.CAP_ERROR_MESSAGE_TASK_REFUSED);

		//SCCP Gt classes
		binding.setAlias(GlobalTitle0001Impl.class, GlobalTitle0001.class.getSimpleName());
		binding.setAlias(GlobalTitle0010Impl.class, GlobalTitle0010.class.getSimpleName());
		binding.setAlias(GlobalTitle0011Impl.class, GlobalTitle0011.class.getSimpleName());
		binding.setAlias(GlobalTitle0100Impl.class, GlobalTitle0100.class.getSimpleName());

		binding.setAlias(XmlCAPDialog.class, DIALOG);
		binding.setClassAttribute(TYPE);
	}

	/**
	 * Serialize passed {@link CAPDialog} object
	 *
	 * @param dialog
	 * @return serialized byte array
	 * @throws XMLStreamException
	 *             Exception if serialization fails
	 */
	public byte[] serialize(XmlCAPDialog dialog) throws XMLStreamException {

		final ByteArrayOutputStream baos = new ByteArrayOutputStream();
		final XMLObjectWriter writer = XMLObjectWriter.newInstance(baos);

		try {

			writer.setBinding(binding);
			writer.setIndentation(TAB);

			writer.write(dialog, DIALOG, XmlCAPDialog.class);
			writer.flush();
			byte[] data = baos.toByteArray();

			return data;
		} finally {
			writer.close();
		}
	}

	/**
	 * De-serialize the byte[] into {@link CAPDialog} object
	 *
	 * @param data
	 * @return de-serialized Dialog Object
	 * @throws XMLStreamException
	 *             Exception if de-serialization fails
	 */
	public XmlCAPDialog deserialize(byte[] data) throws XMLStreamException {
		final ByteArrayInputStream bais = new ByteArrayInputStream(data);
		final XMLObjectReader reader = XMLObjectReader.newInstance(bais);
		try {
			reader.setBinding(binding);
			XmlCAPDialog dialog = reader.read(DIALOG, XmlCAPDialog.class);
			return dialog;
		} finally {
			reader.close();
		}
	}

	/**
	 * De-serialize passed {@link InputStream} into {@link CAPDialog} object
	 *
	 * @param is
	 * @return de-serialized Dialog Object
	 * @throws XMLStreamException
	 *             Exception if de-serialization fails
	 */
	public XmlCAPDialog deserialize(InputStream is) throws XMLStreamException {
		final XMLObjectReader reader = XMLObjectReader.newInstance(is);
		try {
			reader.setBinding(binding);
			XmlCAPDialog dialog = reader.read(DIALOG, XmlCAPDialog.class);
			return dialog;
		} finally {
			reader.close();
		}
	}
}
  • The serialize method serializes Dialog and retruns back byte array.

  • The deserialize is overloaded method. Application can either pass byte[] or InputStream and de-serializes the stream of data to Dialog object.

7.4. Dialog

This section provides the details for XmlCAPDialog

package org.restcomm.camelgateway;

public class XmlCAPDialog implements org.mobicents.protocols.ss7.cap.api.CAPDialog, XMLSerializable {

	private static final String NETWORK_ID = "networkId";
    private static final String DIALOG_TYPE = "type";

	private static final String CAP_APPLN_CONTEXT = "appCntx";

	private static final String SCCP_ORG_ADD = "origAddress";
	private static final String SCCP_DST_ADD = "destAddress";

    private static final String CAP_USER_ABORT_REASON = "capUserAbortReason";
    private static final String P_ABORT_CAUSE_TYPE = "pAbortCauseType";

	private static final String PRE_ARRANGED_END = "prearrangedEnd";

	private static final String NO_ACTIVITY_TIMEOUT = "noActivityTimeOut";

	private static final String RETURN_MSG_ON_ERR = "returnMessageOnError";

//	private static final String REDIRECT_REQUEST = "redirectRequest";

	private static final String CAP_MSGS_SIZE = "capMessagesSize";

	private static final String LOCAL_ID = "localId";
	private static final String REMOTE_ID = "remoteId";

    private static final String INVOKE_WITHOUT_ANSWERS_ID = "invokeWithoutAnswerIds";
    private static final String ASSIGNED_INVOKE_IDS = "assignedInvokeIds";

    private static final String ERROR_COMPONENTS = "errComponents";
    private static final String REJECT_COMPONENTS = "rejectComponents";

	private static final String COMMA_SEPARATOR = ",";

	// Application Context of this Dialog
	protected CAPApplicationContext appCntx;

	protected SccpAddress origAddress;
	protected SccpAddress destAddress;

	private MessageType messageType = MessageType.Unknown;

	private CAPUserAbortReason capUserAbortReason = null;
	private PAbortCauseType pAbortCauseType = null;
	private Boolean prearrangedEnd = null;

	private Long localId;
	private Long remoteId;

	private int networkId;

	private boolean returnMessageOnError = false;

	private Boolean noActivityTimeout = null;

//	private boolean redirectRequest = false;

	private FastList<Long> processInvokeWithoutAnswerIds = new FastList<Long>();
    private FastList<CAPMessage> capMessages = new FastList<CAPMessage>();
    private FastList<Long> assignedInvokeIds = new FastList<Long>();

    private ErrorComponentCap errorComponents = new ErrorComponentCap();
    private RejectComponentCap rejectComponents = new RejectComponentCap();

	private CAPDialogState state = CAPDialogState.Idle;

	public XmlCAPDialog() {
		super();
	}

	/**
	 *
	 */
	public XmlCAPDialog(CAPApplicationContext appCntx, SccpAddress origAddress, SccpAddress destAddress, Long localId,
			Long remoteId) {
		this.appCntx = appCntx;
		this.origAddress = origAddress;
		this.destAddress = destAddress;
		this.localId = localId;
		this.remoteId = remoteId;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#abort(org.mobicents.protocols
	 * .ss7.cap.api.dialog.CAPUserAbortReason)
	 */
	@Override
	public void abort(CAPUserAbortReason capUserAbortReason) throws CAPException {
		this.capUserAbortReason = capUserAbortReason;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#cancelInvocation(java.lang
	 * .Long)
	 */
	@Override
	public boolean cancelInvocation(Long invokeId) throws CAPException {
		throw new CAPException(new OperationNotSupportedException());
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#close(boolean)
	 */
	@Override
	public void close(boolean prearrangedEnd) throws CAPException {
		this.prearrangedEnd = prearrangedEnd;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#closeDelayed(boolean)
	 */
	@Override
	public void closeDelayed(boolean prearrangedEnd) throws CAPException {
		throw new CAPException(new OperationNotSupportedException());
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#getApplicationContext()
	 */
	@Override
	public CAPApplicationContext getApplicationContext() {
		return this.appCntx;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#getGprsReferenceNumber()
	 */
	@Override
	public CAPGprsReferenceNumber getGprsReferenceNumber() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#getLocalAddress()
	 */
	@Override
	public SccpAddress getLocalAddress() {
		return this.origAddress;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#getLocalDialogId()
	 */
	@Override
	public Long getLocalDialogId() {
		return this.localId;
	}

	@Override
	public int getNetworkId() {
		return networkId;
	}

	@Override
	public void setNetworkId(int networkId) {
		this.networkId = networkId;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#getMaxUserDataLength()
	 */
	@Override
	public int getMaxUserDataLength() {
		// TODO Auto-generated method stub
		return 0;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#getMessageUserDataLengthOnClose
	 * (boolean)
	 */
	@Override
	public int getMessageUserDataLengthOnClose(boolean prearrangedEnd) throws CAPException {
		// TODO Auto-generated method stub
		return 0;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#getMessageUserDataLengthOnSend
	 * ()
	 */
	@Override
	public int getMessageUserDataLengthOnSend() throws CAPException {
		// TODO Auto-generated method stub
		return 0;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#getReceivedGprsReferenceNumber
	 * ()
	 */
	@Override
	public CAPGprsReferenceNumber getReceivedGprsReferenceNumber() {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#getRemoteAddress()
	 */
	@Override
	public SccpAddress getRemoteAddress() {
		return this.destAddress;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#getRemoteDialogId()
	 */
	@Override
	public Long getRemoteDialogId() {
		return this.remoteId;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#getReturnMessageOnError()
	 */
	@Override
	public boolean getReturnMessageOnError() {
		return this.returnMessageOnError;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#getService()
	 */
	@Override
	public CAPServiceBase getService() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#getState()
	 */
	@Override
	public CAPDialogState getState() {
		return this.state;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#getTCAPMessageType()
	 */
	@Override
	public MessageType getTCAPMessageType() {
        return this.messageType;
	}

    public void setTCAPMessageType(MessageType messageType) {
        this.messageType = messageType;
    }

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#getUserObject()
	 */
	@Override
	public Object getUserObject() {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#keepAlive()
	 */
	@Override
	public void keepAlive() {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#processInvokeWithoutAnswer
	 * (java.lang.Long)
	 */
	@Override
    public void processInvokeWithoutAnswer(Long invokeId) {
        this.processInvokeWithoutAnswerIds.add(invokeId);
    }

	public void addAssignedInvokeIds(Long invokeId) {
        this.assignedInvokeIds.add(invokeId);
    }

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#release()
	 */
	@Override
	public void release() {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#resetInvokeTimer(java.lang
	 * .Long)
	 */
	@Override
	public void resetInvokeTimer(Long arg0) throws CAPException {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#send()
	 */
	@Override
	public void send() throws CAPException {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.mobicents.protocols.ss7.cap.api.CAPDialog#sendDelayed()
	 */
	@Override
	public void sendDelayed() throws CAPException {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#sendErrorComponent(java
	 * .lang.Long, org.mobicents.protocols.ss7.cap.api.errors.CAPErrorMessage)
	 */
	@Override
	public void sendErrorComponent(Long invokeId, CAPErrorMessage capErrorMessage) throws CAPException {
		this.errorComponents.put(invokeId, capErrorMessage);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#sendInvokeComponent(org
	 * .mobicents.protocols.ss7.tcap.asn.comp.Invoke)
	 */
	@Override
	public void sendInvokeComponent(Invoke invoke) throws CAPException {
		throw new CAPException(new OperationNotSupportedException());

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#sendRejectComponent(java
	 * .lang.Long, org.mobicents.protocols.ss7.tcap.asn.comp.Problem)
	 */
	@Override
	public void sendRejectComponent(Long invokeId, Problem problem) throws CAPException {
        this.rejectComponents.put(invokeId, problem);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#sendReturnResultLastComponent
	 * (org.mobicents.protocols.ss7.tcap.asn.comp.ReturnResultLast)
	 */
	@Override
	public void sendReturnResultLastComponent(ReturnResultLast arg0) throws CAPException {
		throw new CAPException(new OperationNotSupportedException());

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#setGprsReferenceNumber(
	 * org.mobicents.protocols.ss7.cap.api.dialog.CAPGprsReferenceNumber)
	 */
	@Override
	public void setGprsReferenceNumber(CAPGprsReferenceNumber arg0) {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#setLocalAddress(org.mobicents
	 * .protocols.ss7.sccp.parameter.SccpAddress)
	 */
	@Override
	public void setLocalAddress(SccpAddress origAddress) {
		this.origAddress = origAddress;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#setRemoteAddress(org.mobicents
	 * .protocols.ss7.sccp.parameter.SccpAddress)
	 */
	@Override
	public void setRemoteAddress(SccpAddress destAddress) {
		this.destAddress = destAddress;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#setReturnMessageOnError
	 * (boolean)
	 */
	@Override
	public void setReturnMessageOnError(boolean returnMessageOnError) {
		this.returnMessageOnError = returnMessageOnError;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.protocols.ss7.cap.api.CAPDialog#setUserObject(java.lang
	 * .Object)
	 */
	@Override
	public void setUserObject(Object arg0) {
		// TODO Auto-generated method stub

	}

//	/**
//	 *
//	 * @return
//	 */
//	public boolean isRedirectRequest() {
//		return redirectRequest;
//	}
//
//	/**
//	 *
//	 * @param redirectRequest
//	 */
//	public void setRedirectRequest(boolean redirectRequest) {
//		this.redirectRequest = redirectRequest;
//	}

	public Boolean getNoActivityTimeout() {
		return noActivityTimeout;
	}

	public void setNoActivityTimeout(Boolean noActivityTimeout) {
		this.noActivityTimeout = noActivityTimeout;
	}

	/**
	 * Non CAPDialog methods
	 */

	public void addCAPMessage(CAPMessage capMessage) {
		this.capMessages.add(capMessage);
	}

	public boolean removeCAPMessage(CAPMessage capMessage) {
		return this.capMessages.remove(capMessage);
	}

	public FastList<CAPMessage> getCAPMessages() {
		return this.capMessages;
	}

    public FastList<Long> getProcessInvokeWithoutAnswerIds() {
        return this.processInvokeWithoutAnswerIds;
    }

    public FastList<Long> getAssignedInvokeIds() {
        return this.assignedInvokeIds;
    }

    public ErrorComponentCap getErrorComponents() {
        return errorComponents;
    }

    public RejectComponentCap getRejectComponents() {
        return rejectComponents;
    }

	public void reset() {
		this.capMessages.clear();
        this.processInvokeWithoutAnswerIds.clear();
        this.assignedInvokeIds.clear();
        this.errorComponents.clear();
        this.rejectComponents.clear();

        this.noActivityTimeout = null;
	}

    public CAPUserAbortReason getCapUserAbortReason() {
        return capUserAbortReason;
    }

    public PAbortCauseType getPAbortCauseType() {
        return pAbortCauseType;
    }

    public void setPAbortCauseType(PAbortCauseType val) {
        pAbortCauseType = val;
    }

	public Boolean getPrearrangedEnd() {
		return prearrangedEnd;
	}


	@Override
	public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("XmlCAPDialog [");
        if (appCntx != null) {
            sb.append("appCntx=");
            sb.append(appCntx);
        }
        if (origAddress != null) {
            sb.append(", origAddress=");
            sb.append(origAddress);
        }
        if (destAddress != null) {
            sb.append(", destAddress=");
            sb.append(destAddress);
        }
        if (messageType != null) {
            sb.append(", messageType=");
            sb.append(messageType);
        }
        if (pAbortCauseType != null) {
            sb.append(", pAbortCauseType=");
            sb.append(pAbortCauseType);
        }
        if (capUserAbortReason != null) {
            sb.append(", capUserAbortReason=");
            sb.append(capUserAbortReason);
        }
        if (prearrangedEnd != null) {
            sb.append(", prearrangedEnd=");
            sb.append(prearrangedEnd);
        }
        if (noActivityTimeout != null) {
            sb.append(", noActivityTimeout=");
            sb.append(noActivityTimeout);
        }
        if (localId != null) {
            sb.append(", localId=");
            sb.append(localId);
        }
        if (remoteId != null) {
            sb.append(", remoteId=");
            sb.append(remoteId);
        }
        sb.append(", networkId=");
        sb.append(networkId);
        if (returnMessageOnError) {
            sb.append(", returnMessageOnError=");
            sb.append(returnMessageOnError);
        }
//        if (redirectRequest) {
//            sb.append(", redirectRequest=");
//            sb.append(redirectRequest);
//        }
        if (processInvokeWithoutAnswerIds != null && processInvokeWithoutAnswerIds.size() > 0) {
            sb.append(", processInvokeWithoutAnswerIds=");
            sb.append(processInvokeWithoutAnswerIds);
        }
        if (assignedInvokeIds != null && assignedInvokeIds.size() > 0) {
            sb.append(", assignedInvokeIds=");
            sb.append(assignedInvokeIds);
        }
        if (capMessages != null && capMessages.size() > 0) {
            sb.append(", capMessages=");
            sb.append(capMessages);
        }
        if (errorComponents != null && errorComponents.size() > 0) {
            sb.append(", errorComponents=");
            sb.append(errorComponents);
        }
        if (rejectComponents != null && rejectComponents.size() > 0) {
            sb.append(", rejectComponents=");
            sb.append(rejectComponents);
        }
        if (state != null) {
            sb.append(", state=");
            sb.append(state);
        }

        sb.append("]");
	    return sb.toString();
	}



    protected static final XMLFormat<XmlCAPDialog> USSR_XML = new XMLFormat<XmlCAPDialog>(XmlCAPDialog.class) {
        public void write(XmlCAPDialog dialog, OutputElement xml) throws XMLStreamException {
            xml.setAttribute(DIALOG_TYPE, dialog.messageType.name());
            if (dialog.appCntx != null) {
                xml.setAttribute(CAP_APPLN_CONTEXT, dialog.appCntx.name());
            }
            xml.setAttribute(NETWORK_ID, dialog.networkId);
            xml.setAttribute(LOCAL_ID, dialog.localId);
            xml.setAttribute(REMOTE_ID, dialog.remoteId);

            int size = dialog.processInvokeWithoutAnswerIds.size();
            if (size > 0) {
                StringBuffer sb = new StringBuffer();
                for (int count = 0; count < size; count++) {
                    sb.append(dialog.processInvokeWithoutAnswerIds.get(count));
                    if (count != (size - 1)) {
                        sb.append(COMMA_SEPARATOR);
                    }
                }

                xml.setAttribute(INVOKE_WITHOUT_ANSWERS_ID, sb.toString());
            }

            size = dialog.assignedInvokeIds.size();
            if (size > 0) {
                StringBuffer sb = new StringBuffer();
                for (int count = 0; count < size; count++) {
                    sb.append(dialog.assignedInvokeIds.get(count));
                    if (count != (size - 1)) {
                        sb.append(COMMA_SEPARATOR);
                    }
                }

                xml.setAttribute(ASSIGNED_INVOKE_IDS, sb.toString());
            }

            int capMessagsSize = dialog.capMessages.size();

            xml.setAttribute(CAP_MSGS_SIZE, capMessagsSize);

            if (dialog.capUserAbortReason != null) {
                xml.setAttribute(CAP_USER_ABORT_REASON, dialog.capUserAbortReason.name());
            }
            if (dialog.pAbortCauseType != null) {
                xml.setAttribute(P_ABORT_CAUSE_TYPE, dialog.pAbortCauseType.name());
            }

            xml.setAttribute(PRE_ARRANGED_END, dialog.prearrangedEnd);

            xml.setAttribute(NO_ACTIVITY_TIMEOUT, dialog.noActivityTimeout);

            xml.setAttribute(RETURN_MSG_ON_ERR, dialog.returnMessageOnError);

//            xml.setAttribute(REDIRECT_REQUEST, dialog.redirectRequest);

            xml.add((SccpAddressImpl) dialog.origAddress, SCCP_ORG_ADD, SccpAddressImpl.class);
            xml.add((SccpAddressImpl) dialog.destAddress, SCCP_DST_ADD, SccpAddressImpl.class);

            if (dialog.errorComponents.size() > 0)
                xml.add(dialog.errorComponents, ERROR_COMPONENTS, ErrorComponentCap.class);

            if (dialog.rejectComponents.size() > 0)
                xml.add(dialog.rejectComponents, REJECT_COMPONENTS, RejectComponentCap.class);

            if (dialog.capMessages.size() > 0) {
                for (FastList.Node<CAPMessage> n = dialog.capMessages.head(), end = dialog.capMessages.tail(); (n = n.getNext()) != end;) {

                    CAPMessage capMessage = n.getValue();

                    switch (capMessage.getMessageType()) {
                        case initialDP_Request:
                            xml.add((InitialDPRequestImpl) capMessage, CAPMessageType.initialDP_Request.name(),
                                    InitialDPRequestImpl.class);
                            break;
                        case applyCharging_Request:
                            xml.add((ApplyChargingRequestImpl) capMessage, CAPMessageType.applyCharging_Request.name(),
                                    ApplyChargingRequestImpl.class);
                            break;
                        case applyChargingReport_Request:
                            xml.add((ApplyChargingReportRequestImpl) capMessage,
                                    CAPMessageType.applyChargingReport_Request.name(), ApplyChargingReportRequestImpl.class);
                            break;
                        case cancel_Request:
                            xml.add((CancelRequestImpl) capMessage, CAPMessageType.cancel_Request.name(),
                                    CancelRequestImpl.class);
                            break;
                        case connect_Request:
                            xml.add((ConnectRequestImpl) capMessage, CAPMessageType.connect_Request.name(),
                                    ConnectRequestImpl.class);
                            break;
                        case continue_Request:
                            xml.add((ContinueRequestImpl) capMessage, CAPMessageType.continue_Request.name(),
                                    ContinueRequestImpl.class);
                            break;
                        case eventReportBCSM_Request:
                            xml.add((EventReportBCSMRequestImpl) capMessage, CAPMessageType.eventReportBCSM_Request.name(),
                                    EventReportBCSMRequestImpl.class);
                            break;
                        case releaseCall_Request:
                            xml.add((ReleaseCallRequestImpl) capMessage, CAPMessageType.releaseCall_Request.name(),
                                    ReleaseCallRequestImpl.class);
                            break;
                        case requestReportBCSMEvent_Request:
                            xml.add((RequestReportBCSMEventRequestImpl) capMessage,
                                    CAPMessageType.requestReportBCSMEvent_Request.name(),
                                    RequestReportBCSMEventRequestImpl.class);
                            break;

                        case connectToResource_Request:
                            xml.add((ConnectToResourceRequestImpl) capMessage,
                                    CAPMessageType.connectToResource_Request.name(),
                                    ConnectToResourceRequestImpl.class);
                            break;
                        case furnishChargingInformation_Request:
                            xml.add((FurnishChargingInformationRequestImpl) capMessage,
                                    CAPMessageType.furnishChargingInformation_Request.name(),
                                    FurnishChargingInformationRequestImpl.class);
                            break;
                        case promptAndCollectUserInformation_Request:
                            xml.add((PromptAndCollectUserInformationRequestImpl) capMessage,
                                    CAPMessageType.promptAndCollectUserInformation_Request.name(),
                                    PromptAndCollectUserInformationRequestImpl.class);
                            break;
                        case promptAndCollectUserInformation_Response:
                            xml.add((PromptAndCollectUserInformationResponseImpl) capMessage,
                                    CAPMessageType.promptAndCollectUserInformation_Response.name(),
                                    PromptAndCollectUserInformationResponseImpl.class);
                            break;

                        default:
                            break;
                    }
                }
            }
		}

		public void read(InputElement xml, XmlCAPDialog dialog) throws XMLStreamException {
            MessageType mt = MessageType.valueOf(xml.getAttribute(DIALOG_TYPE, MessageType.Unknown.name()));
            if (mt != MessageType.Unknown)
                dialog.messageType = mt;
            else
                dialog.messageType = null;

            String appCtxStr = xml.getAttribute(CAP_APPLN_CONTEXT, null);

			if (appCtxStr != null) {
				dialog.appCntx = CAPApplicationContext.valueOf(CAPApplicationContext.class, appCtxStr);
			}
			dialog.networkId = xml.getAttribute(NETWORK_ID, 0);
			dialog.localId = xml.getAttribute(LOCAL_ID, 0l);
			dialog.remoteId = xml.getAttribute(REMOTE_ID, 0l);

            String sb = xml.getAttribute(INVOKE_WITHOUT_ANSWERS_ID, null);
            if (sb != null) {
                String[] longStrsArr = sb.split(COMMA_SEPARATOR);
                for (int count = 0; count < longStrsArr.length; count++) {
                    dialog.processInvokeWithoutAnswer(Long.parseLong(longStrsArr[count]));
                }
            }
            sb = xml.getAttribute(ASSIGNED_INVOKE_IDS, null);
            if (sb != null) {
                String[] longStrsArr = sb.split(COMMA_SEPARATOR);
                for (int count = 0; count < longStrsArr.length; count++) {
                    dialog.addAssignedInvokeIds(Long.parseLong(longStrsArr[count]));
                }
            }

			int capMssgsSize = xml.getAttribute(CAP_MSGS_SIZE, 0);

            String capUsrAbrtReaStr = xml.getAttribute(CAP_USER_ABORT_REASON, null);
            if (capUsrAbrtReaStr != null) {
                dialog.capUserAbortReason = CAPUserAbortReason.valueOf(CAPUserAbortReason.class, capUsrAbrtReaStr);
            }
            String pAbortCauseTypeStr = xml.getAttribute(P_ABORT_CAUSE_TYPE, null);
            if (pAbortCauseTypeStr != null) {
                dialog.pAbortCauseType = CAPUserAbortReason.valueOf(PAbortCauseType.class, pAbortCauseTypeStr);
            }

			String preArrEndStr = xml.getAttribute(PRE_ARRANGED_END, null);
			if (preArrEndStr != null) {
				dialog.prearrangedEnd = Boolean.parseBoolean(preArrEndStr);
			}

			String noActivityTimeoutStr = xml.getAttribute(NO_ACTIVITY_TIMEOUT, null);
			if(noActivityTimeoutStr != null){
				dialog.noActivityTimeout = Boolean.parseBoolean(noActivityTimeoutStr);
			}

			dialog.returnMessageOnError = xml.getAttribute(RETURN_MSG_ON_ERR, false);

//			dialog.redirectRequest = xml.getAttribute(REDIRECT_REQUEST, false);

			dialog.origAddress = xml.get(SCCP_ORG_ADD, SccpAddressImpl.class);
			dialog.destAddress = xml.get(SCCP_DST_ADD, SccpAddressImpl.class);

            ErrorComponentCap eComp = xml.get(ERROR_COMPONENTS, ErrorComponentCap.class);
            if (eComp != null)
                dialog.errorComponents = eComp;

            RejectComponentCap rComp = xml.get(REJECT_COMPONENTS, RejectComponentCap.class);
            if (rComp != null)
                dialog.rejectComponents = rComp;

			for (int count = 0; count < capMssgsSize; count++) {

				CAPMessage capMessage = xml.get(CAPMessageType.initialDP_Request.name(), InitialDPRequestImpl.class);

				if (capMessage == null) {
					capMessage = xml.get(CAPMessageType.applyCharging_Request.name(), ApplyChargingRequestImpl.class);
				}

				if (capMessage == null) {
					capMessage = xml.get(CAPMessageType.applyChargingReport_Request.name(),
							ApplyChargingReportRequestImpl.class);
				}

				if (capMessage == null) {
					capMessage = xml.get(CAPMessageType.cancel_Request.name(), CancelRequestImpl.class);
				}

				if (capMessage == null) {
					capMessage = xml.get(CAPMessageType.connect_Request.name(), ConnectRequestImpl.class);
				}

				if (capMessage == null) {
					capMessage = xml.get(CAPMessageType.continue_Request.name(), ContinueRequestImpl.class);
				}

				if (capMessage == null) {
					capMessage = xml.get(CAPMessageType.eventReportBCSM_Request.name(),
							EventReportBCSMRequestImpl.class);
				}

				if (capMessage == null) {
					capMessage = xml.get(CAPMessageType.releaseCall_Request.name(), ReleaseCallRequestImpl.class);
				}

                if (capMessage == null) {
                    capMessage = xml.get(CAPMessageType.requestReportBCSMEvent_Request.name(),
                            RequestReportBCSMEventRequestImpl.class);
                }

                if (capMessage == null) {
                    capMessage = xml.get(CAPMessageType.connectToResource_Request.name(), ConnectToResourceRequestImpl.class);
                }
                if (capMessage == null) {
                    capMessage = xml.get(CAPMessageType.furnishChargingInformation_Request.name(), FurnishChargingInformationRequestImpl.class);
                }
                if (capMessage == null) {
                    capMessage = xml.get(CAPMessageType.promptAndCollectUserInformation_Request.name(), PromptAndCollectUserInformationRequestImpl.class);
                }
                if (capMessage == null) {
                    capMessage = xml.get(CAPMessageType.promptAndCollectUserInformation_Response.name(), PromptAndCollectUserInformationResponseImpl.class);
                }

				dialog.addCAPMessage(capMessage);
			}
		}
	};
}

Appendix A: Revision History