Parlay RA CallBlocking Service Example
A simple CallBlocking service is included in the mobicents-parlay-ra source code as an example of how to use the Parlay RA. The following instructions detail the installation for this service and provide a simple tutorial detailing the key design elements.
Installing the CallBlocking Sample Service
The Callblocking service can be installed after installing the PArlay RA.
- From the home directory of your mobicents-parlay-ra rrepository run
cd callblocking
ant build-auto-deploy
Running ant deploy will perform the following steps
- Build and package all CallBlocking Sbb code and type definitions
- Copy the deployable unit to the Mobicents Slee installation
- Copy the beanshell deployment script to the Mobicents Slee installation
The beanshell deployment script performs the following steps
- Installs the CallBlocking service
- Activates the CallBlocking service
Parlay CallBlocking Service Tutorial
The Parlay CallBlocking service example is based on the JCC CallBlocking service included with the JAIN SLEE Reference Implementation.
Service Overview
The CallBlocking service interrupts all originating call attempts to a predetermined set of addresses. The originating address is then compared to a provisioned set of blocked addresses for the destination number. If the address is blocked the call will be terminated by the service otherwise the call is continued.
The CallBlocking service example in this tutorial uses the Multi-Party Call Control Service (MPCCS) on a Parlay Gateway to establish the call interrupt and perform the call interactions. All Parlay Gateway interaction is performed via the mobicents-parlay-ra resource adaptor.
The Parlay MPCCS service allows control of multi-party calls via a network independant API so the call flows and code used in this example could be ran on SIP or INAP based network elements.
Component Overview
The CallBlocking Service contains the following key components
- CallBlocking Sbb
- sets up the call interrupt when the service is started
- handles all call interrupt events at runtime
- Address Profile CMP
- contains a list of blocked addresses for a specific destination address
- Deployment Descriptors
- standard slee mechanism for defining deployable components and their configuration
Service Design
Service Definition
The CallBlocking-service.xml descriptor is as follows:
<service-xml>
<service>
<service-name>Parlay Call Blocking</service-name>
<service-vendor>org.mobicents</service-vendor>
<service-version>1.0</service-version>
<root-sbb>
<sbb-name>Parlay Call Blocking Sbb</sbb-name>
<sbb-vendor>org.mobicents</sbb-vendor>
<sbb-version>1.0</sbb-version>
</root-sbb>
<default-priority>0</default-priority>
<address-profile-table>CallBlockingProfiles</address-profile-table>
</service>
</service-xml>
There are two important notes to be made about it:
- The service is uniquely identified in the SLEE container by the tuple (service-name, service-vendor, service-version)
- The root SBB must be referenced via unique identifier composed of the tuple (sbb-name, sbb-vendor, sbb-version)
The service descriptor file is bundled in a SLEE Deployment Unit along with the SBB archive and Profile archive. The CallBlocking?-DU.jar file has the following structure:
-
-
/CallBlocking-service.xml
-
/META-INF/deployable-unit.xml. This file simply lists the SLEE archives and services contained in the DU
-
/jar/CallBlocking-sbb.jar. Contains the CallBlockingSbb and its service description. The structure of this Sbb will be detailed in the following sections.
-
/jar/CallBlocking-profile.jar.
CallBlocking Sbb Definition
The CallBlockingSbb is implemented in the CallBlockingSbb.java class and it is announced to the SLEE via an sbb-jar.xml descriptor file. Both files are bundled in one archive - CallBlocking-sbb.jar, with the following structure:
-
-
/META-INF/sbb-jar.xml - SBB descriptor file
-
/org/mobicents/* - Java classes
Accessing the Parlay Gateway
Access to the Parlay Gateway is via the Parlay RA. As the Parlay RA interfaces are defined in the RA Type Definition the CallBlockingSbb must declare a binding to the RA in it's SBB descriptor file. This is performed via a <resource-adapter-type-binding>
<resource-adaptor-type-binding>
<resource-adaptor-type-ref>
<resource-adaptor-type-name>parlay</resource-adaptor-type-name>
<resource-adaptor-type-vendor>org.mobicents</resource-adaptor-type-vendor>
<resource-adaptor-type-version>4.2</resource-adaptor-type-version>
</resource-adaptor-type-ref>
<activity-context-interface-factory-name>
slee/resources/ParlayRA/parlayacif
</activity-context-interface-factory-name>
<resource-adaptor-entity-binding>
<resource-adaptor-object-name>
slee/resources/parlay/4.2/resourceAdapterSbbInterface
</resource-adaptor-object-name>
<resource-adaptor-entity-link>
ParlayRA
</resource-adaptor-entity-link>
</resource-adaptor-entity-binding>
</resource-adaptor-type-binding>
Consult the Slee Specification for more information on establishing this binding.
The Sbb can then access the RA via its local JNDI tree in the Slee
try {
Context ctx = (Context) new InitialContext()
.lookup("java:comp/env");
resourceAdapterSbbInterface = (ParlayResourceAdapterSbbInterface) ctx
.lookup(RA_JNDI_NAME);
Setting up the Call Interrupt
The Parlay OSA APIs use a notification pattern to inform applications of network originated events. To interrupt originating call attempts a notifiction with the appropriate criteria must be created.
The notification will be created using an MPCCS Service Capability Feature (SCF) instance on a Parlay Gateway. To access the SCF the application must first esablish a connection via the RA with the SCF. This is performed using the Parlay RA connection pool
connection = resourceAdapterSbbInterface.getParlayConnection();
TpServiceIdentifier serviceIdentifier = connection.getService(
"P_MULTI_PARTY_CALL_CONTROL", new Properties());
IpMultiPartyCallControlManagerConnection callControlManagerConnection =
(IpMultiPartyCallControlManagerConnection) connection.getIpServiceConnection(serviceIdentifier);
Note: No properties have been defined here. On a normal gateway the service properties can be used to distinguish between different types of SCF e.g. MPCCS-SIP or MPCCS-INAP.
Once an IpMultiPartyCallControlManagerConnection has been established it can be used to create a notification
int assignmentID = callControlManagerConnection
.createNotification(createControlCallsToNotificationRequest(
ALL_E164_RANGE, ALL_E164_RANGE));
The createNotification(createControlCallsToNotificationRequest() operation is a utility method on the Sbb that constructs the appropriate event criteria for the call interrupt. An MPCCS call interrupt consists of a scope which defines the originating and terminating address ranges, an event set which defines the transitions in the Parlay Call FSM at which the notifications should occur and a monitor mode which specifies whether the application wishes to interrupt the call or merely receive notifications of the call state.
In this example an interrupt has been created between all E164 originating and terminating address ranges. An E164 address range is defined as follows:
private static final TpAddressRange ALL_E164_RANGE = new TpAddressRange(
TpAddressPlan.P_ADDRESS_PLAN_E164, "*", "", "");
A SIP address range could be defined just as easily e.g.
private static final TpAddressRange ALL_SIP_RANGE = new TpAddressRange(
TpAddressPlan.P_ADDRESS_PLAN_SIP, "sip:*@*", "", "");
The event set is P_CALL_EVENT_ADDRESS_COLLECTED as this is one of the events pertaining to an originating call attempt.
The monitor mode is P_CALL_MONITOR_MODE_INTERRUPT as we wish to interrupt and have control of the call.
We wish to establish the call interrupt as soon as the service is started therefore the CallBlockingSbb will subscribe to the ServiceStartedEvent which is a standard Slee event. This is a two-fold process. Firstly the Sbb deployment descriptor must be updated with the appropriate subscription information as follows:
<event event-direction="Receive" initial-event="True">
<event-name>ServiceStartedEvent</event-name>
<event-type-ref>
<event-type-name>javax.slee.serviceactivity.ServiceStartedEvent</event-type-name>
<event-type-vendor>javax.slee</event-type-vendor>
<event-type-version>1.0</event-type-version>
</event-type-ref>
<initial-event-select variable="ActivityContext" />
</event>
Secondly the Sbb must provide a concrete implementation of the onServiceStartedEvent(ServiceStartedEvent e) method:
public void onServiceStartedEvent(ServiceStartedEvent event,
ActivityContextInterface aci) {
try {
// ...
// other init can go here
// ...
setupCallInterrupt();
}
catch (NamingException ne) {
trace(Level.WARNING,
"ERROR: Exception caught processing setSbbContext", ne);
}
}
Handling Call Interrupts
The notification mechanism for handling call interrupts has already been mentioned above. The Parlay RA maps these MPCCS notification reports to ReportNotificationEvents in the Slee. The CallBlockingSbb must therefore also subscripe to these events. Again this is a two-fold process requiring subscription information in the SBB deployment descriptor and a concrete event handling implementation in the Sbb.
DD Code:
<event event-direction="Receive" initial-event="True">
<event-name>ReportNotificationEvent</event-name>
<event-type-ref>
<event-type-name>
org.mobicents.csapi.jr.slee.cc.mpccs.ReportNotificationEvent
</event-type-name>
<event-type-vendor>org.mobicents</event-type-vendor>
<event-type-version>4.2</event-type-version>
</event-type-ref>
<initial-event-select variable="ActivityContext" />
</event>
Sbb Code:
public void onReportNotificationEvent(ReportNotificationEvent event,
ActivityContextInterface aci) {
// ... event handler code
}
The ReportNotificationEvent encapsulates all the information an Sbb needs to interact with the Parlay Call. The data can be broken down as follows:
- Service identifiers
- Parlay application level identifiers that identify the specific service instance the event originated from, the call the interrupt occurred on and any legs involved in the call. These identifiers represent an Activity in the RA and can be used to establish connections to the activity for service interaction.
- Call event information
- Details the call information including originating and destination addresses and the current state of the call. These types are identical to those in the Parlay specifications.
The CallBlocking service requires the originating address, destination address and the call identifier to function. On receipt of a notification event the Sbb attempts to establish a connection with the call using the service identifier and call identifier. These identifiers together uniquely identify the call Activity in the RA.
try {
// Get a call connection
callConnection = getIpMultiPartyCallConnection(event.getService(),
event.getCallReference());
If the connection is established then the call originating and destination addresses are obtained
// Get call originator and destination from the event
TpAddress originatingAddress =
event.getNotificationInfo().CallNotificationReportScope.OriginatingAddress;
TpAddress destinationAddress =
event.getNotificationInfo().CallNotificationReportScope.DestinationAddress;
The originating address is then compared to the blocked list for the destination address using the AddressProfileCMP. The profile is accessed using the Slee ProfileFacility
// find address profile for destination address
ProfileID id = profileFacility.getProfileByIndexedAttribute(
"CallBlockingProfiles", "addresses", new Address(
AddressPlan.E164, destinationAddress.AddrString));
CallBlockingAddressProfileCMP profile = getProfile(id);
This code accesses the CallBlockingProfiles profile in the slee. Refer to the Slee Specification for more information on establishing Profiles for Sbbs.
Depending on whether the address is matched in the profile table the call is either continued or terminated. Terminating a call in MPCCS is performed using the release() method. Alternatively the deassignCall() operation relinquishes the Sbb service's control of the call which will implicitly allow it to continue in the network.
if (isBlocked) {
// block the call
// Release ends the call on the network and in the Parlay
// Gateway.
callConnection.release(TpReleaseCause.P_USER_NOT_AVAILABLE);
}
else {
// deassign implicitly continues the call and ends it on the
// Parlay gateway
callConnection.deassignCall();
}
Further reading
-- Main.ivanmcshane - 27 Apr 2006
|