SipExchange Home
Terminologies
SipExchange Overview
SipExchange Basics
System Administration
Howto
External Call Control
External Call Control Javadoc
|
Feature Developers Guide
This guide tells you how you can create new features and services using
the
SipExchange external call control mechanisms. To understand this
section fully, please make sure that you have read
the following topics first:
You will also need the javadocs
for the SipExchange external call control API.
Table
of Contents
Conventions
followed in this document
- We have used the term "directory" to specify a file
location. This is a common Unix convention. In the Windows environment,
the term "folder" is used to mean the same thing.
- We have used the Unix directory naming convention in this
document. In the Unix environment, a directory hierarchy is specified
by the "/" separator. In the Windows environment, the "\" separator is
used. In addition, Unix systems do not use drive letters as in Windows.
If you are using Windows, you will need to modify the commands
accordingly. For example, if we stated $JIPLET_HOME/bin and you are
using Windows, it may translate to C:\jiplet-standalone\bin.
- We have used $SIPEXCHANGE_HOME or similar names to specify
variables. While installing/configuring, you will need to replace these
variables with the actual value. For example, in this document, the
variable $SIPEXCHANGE_HOME has been used to specify the directory where
the SipExchange code binary is unpackaged. We have commonly used the
following variables:
- $JAVA_HOME - directory where the Java Runtime Environment
(JRE) is installed.
- $SIPEXCHANGE_HOME - directory where the SipExchange
software is unpacked.
- $JBOSS_HOME - directory where JBOSS is installed.
- $HOST - host name/IP address of the system where the
jiplet container is installed.
- $RUN - the JBOSS run mode (default, minimal, all, etc.)
- Commands are specified using bold. You need to enter the command
by typing/pasting the command and pressing the Enter/Return key.
Although in the Unix world this may seem natural, in the Windows
environment, lots of users are lost when it comes to entering a
command. Also, the prompts "#" or "C:\>" are shown, do not enter
them.
Overview
To create a new feature or a service, you will have
to create a Service Control Point (SCP) and
administer the SipExchange system so that the system encounters a
trigger at specified point(s) of a call and invokes a service at the
SCP. When the SCP service is invoked, the feature logic that you have
created must be able to respond appropriately to the invocation.
To create a service, you need to be a proficient Java programmer with a
good understanding of the Jboss Remoting API for the underlying
infrastructure. As explained in the External Call Control section,
SipExchange uses the JBoss Remoting API for communication between
SipExchange and SCP. You can get more information and documentation
about that API from here.
This section will demonstrate the use of the remoting API and how to
use the API to develop a feature or a service. If you want to see the
source code, download the source distribution of SipExchange and unpack
the distribution. The source code for SipExchange is located in the
"src" directory and the Java class is org.cafesip.sipexchange.inservice.server.InServiceHandler.
Example service
The example service is a simple service that
demonstrates many of the external call control features of the
SipExchange server. You can create triggers for subscribers and domains
with the "feature" and the "parameter" fields set in a predefined way
as explained below. When a trigger is encountered, the
SipExchange server invokes the SCP service. Based on the feature and
parameter field settings, the SCP sends an appropriate response as
explained below.
Here are the rules for how you set the feature and the parameter fields
while creating a trigger.
When creating a subscriber trigger, you can set the "feature"
field to any unique name. The "parameter" field is set as per the
format "action=something" where action is the name of the action and
something is an action parameter. This is described in more details as
follows:
- If you want the SCP to send a continue response, set the
parameter field as "continue=something".
- If you want the SCP to send a terminate response, set the
parameter field as "disconnect=$reason". Replace the $reason with a
real reason phrase like - "you have not paid your bills".
- If you want the SCP to send a redirect response, set
the parameter field as "reroute=$sipaddress". Replace the $sipaddress
with a SIP address. Example: sip:amit@cafesip.org.
- If you want the SCP to send a forward response, set
the parameter
field as "forward=$sipaddresses". Replace the $sipaddresses with one or
more SIP address separate by a semi-colon (;) delimiter. Example:
sip:amit@cafesip.org;sip:becky@cafesip.org.
When creating a domain trigger, you must set the feature name to any
unique name. The parameter field is set as per the format
"pattern=$somepattern¶m=$someparam". As explained in the External Call Control section,
the $somepattern must be a regular expression against which the
SipExchange server matches the called address. The $someparam uses the
same syntax as described for the subscriber trigger above. An example
of how a domain trigger parameter can be set is:
pattern=operator¶m=forward=sip:amit@cafesip.org;sip:becky@cafesip.org
In the above case, a call to sip:operator@somedomain (where somedomain
is the name of the domain for which you assigned the trigger), is
routed to the SCP which directs the SipExchange server to forward the
call to sip:amit@cafesip.org and sip:becky@cafesip.org. Note that we
have used a plain string, not a regular expressions, in the
pattern field but you can use regular expressions if you want to.
This example service is packaged with the SipExchange distribution and
is installed as a part of SipExchange. To use this service, while
adding a trigger, populate the "Service Controller" field with the URL socket://$HOSTNAME:6666
where $HOSTNAME is the host name or IP address of the server running
SipExchange.
You can view the source code for the example service here.
Service code
development
Each feature that you create will be in the form of an SCP service. An
SCP service can handle more than one feature if you think you want to
do it that way. Creating a service involves creating a Java class that
implements the interface org.jboss.remoting.ServerInvocationHandler as
shown below.
import
org.jboss.remoting.ServerInvocationHandler;
public class InServiceHandler
implements ServerInvocationHandler
{
....
The main method that you have to implement is the invoke() method
as shown below:
/*
* @see
org.jboss.remoting.ServerInvocationHandler#invoke(org.jboss.remoting.InvocationRequest
*/
public Object
invoke(InvocationRequest req) throws Throwable
{
TriggerInfo t = (TriggerInfo) req.getParameter();
System.out.println("Received an invoke from a client\n"
+ printTriggerInfo(t));
...
The Jboss service calls this method when the SipExchange server
invokes the service and this is where you have to add your feature
logic. The parameter to this method is used to pass the trigger
information as shown in the first line of the method. For more details,
read the javadocs for the TriggerInfo class. Note that
TriggerInfo is the base class for call the Trigger classes. The actual
trigger class that is passed as a parameter is one of the following:
- org.cafesip.sipexchange.inservice.shared.CalledAddressTermTrigger
: for CalledAddress trigger
- org.cafesip.sipexchange.inservice.shared.CalledBusyTermTrigger
: for CalledBusy trigger
- org.cafesip.sipexchange.inservice.shared.CalledNoAnswerTermTrigger
: for CalledNoAnswer trigger
- org.cafesip.sipexchange.inservice.shared.CalledNotAvailableTermTrigger
: for CalledNotAvailable trigger
- org.cafesip.sipexchange.inservice.shared.MakeCallOrigTrigger
: for MakeCall trigger
- org.cafesip.sipexchange.inservice.shared.ReceivedCallTermTrigger
: for ReceivedCall trigger
See the javadocs for the above classes for details. If you have written
a service that can receive multiple types of trigger in the same
invoke() method, you can determine the trigger type by using the
instanceof operator. For example:
TriggerInfo
t = (TriggerInfo) req.getParameter();
if (t instanceof org.cafesip.sipexchange.inservice.shared.ReceivedCallTermTrigger)
{
// logic for handling the ReceivedCall trigger
....
}
else if (t instanceof org.cafesip.sipexchange.inservice.shared.MakeCallOrigTrigger)
{
// logic for handling the MakeCall trigger
....
}
.....
The method returns an
object which is received by the SipExchange server. The returned object
must be of the type that the SipExchange server recognizes. They can be
one of the following:
- org.cafesip.sipexchange.inservice.shared.ContinueResponse
- org.cafesip.sipexchange.inservice.shared.RerouteResponse
- org.cafesip.sipexchange.inservice.shared.TerminateResponse
Read the javadocs for these classes for details on what parameters can
be set on these classes. The following code segment demonstrates how a
response is populated (continuing with the example service introduced
previously) and returned:
if (action.equals("forward") == true)
{
RerouteResponse r = new RerouteResponse();
StringTokenizer addresses = new StringTokenizer(aparam, ";");
int count = addresses.countTokens();
String[] addr = new String[count];
for (int i = 0; i < count; i++)
{
String address = addresses.nextToken();
addr[i] = address;
}
System.out.println("Sending a forward response with address "
+ aparam);
r.setRerouteAddresses(addr);
return r;
}
Setting
up the development environment
To set up the development environment, you will need the SipExchange
binary distribution that you may have already downloaded and installed.
Follow the steps outlined below:
- Add all the jar files except the MySQL JDBC driver into
your CLASSPATH environment.
- Create a source directory and the Java source package that
you want your class to be under. Example:
org.cafesip.sipexchange.inservice.server .
- Create a Java class and the feature service as outlined in
the above section.
- Compile the Java classes that you may have created using a
Java compiler.
- Package the classes and libraries as explained below.
- Deploy the service as explained below.
Packaging the service
The way you want to package your service depends on whether you want to
run the
service as a standalone Java application or whether you want to run the
service inside Jboss. One important thing to note is that the service
that you created does not have to be located in the same server where
the SipExchange application is running. If you decide to run the
service that you created on the same system, we recommend that you
package your service as a Jboss service. If you are running the service
in a different system, and you do not have Jboss J2EE server installed
on the system or the system does not meet the requirements for
installing a Jboss server, it may be easier to package the
software as a standalone application.
To package your service as a standalone application, you may have to
create the Main class as well as other classes that Jboss requires for
you to setup the remoting service. Please refer to the Jboss web site
for detailed documentation. You may also need shell scripts to start
and stop the service as well as install the service as a Windows or
Linux service.
To package your service as a JBOSS service, you need to create a
service
archive (SAR).
You need to have a directory structure as shown in the above diagram.
The top-level directory, shown as "sipex-inservice", above, must
have the following:
- A sub-directory called META-INF
- All the jar files that are required by the service. In the
above diagram, the JBOSS remoting API jar files are shown.
- The classes following the package directory structure if
you decide to use classes instead of jars. The "org" directory contains
the classes.
The META-INF directory contains the deployment descriptors.
- jboss-service.xml contains the service descriptor. Here is
a sample jboss-service.xml. Look for
the XML element
<handler subsystem="sipexchange">org.cafesip.sipexchange.inservice.server.InServiceHandler</handler>
and replace the class name with the fully-qualified name of the service
class you created. For modifying further, read the documentation
provided in the comments.
- A sample connector.xml is show here.
You may need to modify this page if you want to provide additional
protocol support.
You can create the package using an Ant script. Once the directory
structure is laid out as shown above and all the files are in place,
using the jar utility, you can package all the directories and files
under the sipex-inservice directory into a service archive (SAR). The
following ant code segment shows you an example of packaging that we
have used:
<mkdir dir="${project.deploy.root}/sipex-inservice/META-INF"/>
<copy todir="${project.deploy.root}/sipex-inservice/META-INF">
<fileset dir="${project.conf.root}">
<include name="connector.xml"/>
<include name="jboss-service.xml"/>
</fileset>
</copy>
<copy todir="${project.deploy.root}/sipex-inservice">
<fileset dir="${project.src.root}">
<include name="org/cafesip/sipexchange/inservice/**/*.class"/>
</fileset>
</copy>
<copy todir="${project.deploy.root}/sipex-inservice">
<fileset dir="${project.lib.root}/remoting">
<include name="*.jar"/>
</fileset>
</copy>
<jar destfile="${project.home}/sipex-inservice.sar">
<zipfileset dir="${project.deploy.root}/sipex-inservice"
includes="**/*"/>
</jar>
Deploying the service
Once you have packaged your service as described above, you need to
deploy the service.
For a standalone application, simply run the application or deploy it
as a Linux
or Windows service by running the shell script that you have created.
For deploying as a Jboss service, copy the sar file you created to the
$JBOSS_HOME/server/$RUN/deploy directory.
Now the SipExchange server should be ready to access the service.
|