Jump to content
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
HP.com home

The Diameter Sh Java API: A Quick Tutorial

Overview

Learn how to develop a Java application based on the Diameter Sh Protocol API.

On this page  Skip past table of contents

Introduction

This page describes the way to develop a Diameter Sh application using HP OpenCall Diameter, as defined in 3GPP TS 29.328 & 29.329.

Sh is the interface defined by 3GPP between the HSS (Home Subscriber Server) and the AS (Application Server) allowing:

For more details and information on the HP OpenCall Diameter API usage, please refer to the documentation and Javadoc available with the SDK.

This tutorial aims at giving you the ability to develop a basic Sh application using the HP OpenCall Diameter Java API. In order to take maximum benefits from it, you should meet the following prerequisites:

Presentation of the HP OpenCall Diameter Sh Java interfaces

Like all other Diameter-based applications, the Sh application relies on all the Diameter base protocol interfaces (DiameterFactory, DiameterStack …). The Sh application code structure itself is identical to the base-protocol one: it is even possible to develop a Sh application using only the base protocol APIs.

However in order to ease the development of Sh applications, HP OpenCall Diameter provides a set of Sh-dedicated Java interfaces on top of the Base Protocol API. These interfaces derive directly from the base protocol interfaces:

Note: DiameterShListener is compatible with Sh Release 5. DiameterShR6Listener supports the additional AVPs of Sh Release 6.

The DiamShClient & DiamShServer example applications

DiamShClient.java and DiamShServer.java are client and server programs that implement a 3GPP Sh Diameter application exchanging UDR / UDA messages (User Data Request, User Data Answer). The client application (playing the role of an Application Server) makes use of Sh standard message (UDR) and AVPs to request the registration information for a given user to the server (acting as the HSS – Home Subscriber Server). The server answers with an UDA providing the user’s registration state to the client.

The complete source code for the applications is available here: DiamShClient.java and DiamShServer.java. These examples may be used as a starting point to develop a real-world Sh application.

In this tutorial, we will review in details the steps that are specific to Sh application development, assuming that the reader has the knowledge of the Base Protocol application development. For the sake of simplicity, the source code shown in this page is not an exact copy of what you will find in DiamShClient.java and DiamShServer.java. However, the majority of the operations that are performed by these example applications are explained below.

Note also that the code below is included here for conceptual purposes only and may lack code grammar coherence (mostly: check for null references, and catch DiameterExceptions ).

The following diagram describes the behavior of the example applications:

DiameterShClient - DiameterShServer

Since the code structure of the Sh application is the same as the base-protocol applications, we will focus on the Sh specific elements in the next sections

Application initialization

The steps that are required to initialize the Diameter stack for an Sh application are mostly the same as for any other HP OpenCall Diameter application. Therefore, we won't go through all these steps again.

There is however a difference concerning the registration of the protocol dictionary for the Sh interface. When writing a custom application on top of the Diameter Base Protocol API, the Diameter stack has to be provided with an XML fragment that describes the commands and AVPs that will be used by the application, as described in the base protocol tutorial. This step is not required when using the Sh API. Indeed, the OpenCall Diameter stack will take care of automatically extending the base protocol dictionary with the Sh syntax when a DiameterShProvider object is instantiated.

A Diameter Sh application is represented by instances of the class DiameterShProvider and the interface DiameterShListener.

DiameterShListener represents the Diameter Sh application interface. It provides a set of Sh-dedicated callback functions that must be implemented by the application, easing the Sh message reception and handling.

The DiameterShProvider is used by the user code to send Sh messages.

These interfaces are defined in the package com.hp.opencall._3gpp.sh, that must be imported.

A typical Diameter Sh application implements the DiameterShListener, as follows (Sh specific code fragments are represented in bold):

import com.hp.opencall.diameter.*;
import com.hp.opencall.diameter._3gpp.sh.*;

class DiameterShClientApplicationSolution 
implements DiameterShListener {

	DiameterStack myStack;
	DiameterShProvider myShProvider;
	
	// Class constructor
	DiameterShClientApplicationSolution(String[] args)
	 {
		DiameterFactory myFactory = DiameterFactory.getInstance();
		
		//creates a DiameterStack
		String localRealm = “ExampleRealm”;
		String localFQDN = “localhost.localdomain.com”;

		// creates a DiameterStack
		myStack = myFactory.createDiameterStack(localRealm,
					localFQDN, myStackProperties);

		// Create provider using DiameterStack’s
		// createDiameterShProvider() method
		myShProvider = myStack. createDiameterShProvider(null);
		
		// Attach the DiameterShListener to the provider using
		// setDiameterShListener().
		// Note that using setDiameterListener() does not work
		myShProvider.setDiameterShListener(this);
		
		// create a listening point for incoming messages
		myStack.createDiameterListeningPoint(localURI);
			
		// Create a route to peer, using “Sh” as the 
		// application name
		myStack.createDiameterRoute("Sh", peerRealm, peerURI, 1);
					
	} // end of constructor

Creating and sending Sh messages

A Diameter Sh application uses the same API as any other OpenCall Diameter application to send messages. However, Sh being a stateless interface, the messages must be sent directly using the DiameterShProvider, without creating any session.

Although it is possible to build Sh messages using only the Base Protocol API (more specifically, the DiameterMessageFactory interface), it is much more desirable to use the specially designed DiameterShMessageFactory for that purpose. This interface permits the creation of complete Sh messages in a single call. It is then possible to take advantage of the Base Protocol API to add any custom AVP to the Sh message.

Here’s an example of how to create a User-Data-Request message and send it statelessly.
void sendShUserDataRequest() 
{
	// get the Sh message factory
	DiameterShMessageFactory myShMessageFactory =
	myStack.getDiameterShMessageFactory();
			
	//Build UDR message contents, requesting the 
	// IMS user state from the HSS.
	DiameterMessage UDR = 
	myShMessageFactory.createUserDataRequest(
	peerRealm,
	"sip:john.doe@hp.com",
	DiameterShMessageFactory.PUBLIC_IDENTITY_AVP,
	DiameterShMessageFactory.IMS_USER_STATE);	
	
	//send message
	myShProvider.sendMessage(UDR);
}

Note: Additionally to setting the base protocol mandatory parameters, the OpenCall Diameter stack takes care of automatically inserting some Sh mandatory AVPs values into the outgoing Diameter messages. The following table shows which values are concerned for Sh messages. These AVPs have always the same value for Sh messages.

Header field or AVP May be added by the stack? Value
Auth-Session-State Yes NO_STATE_MAINTAINED as defined in RFC3588 section 8.11
Vendor-Specific-Application-id Yes Grouped AVP with Vendor_id set to 3GPP (10415) and application_id set to Sh (16777217) as defined in Sh Dictionary

Handling events

Like any application using HP OpenCall Diameter, an Sh application can receive events from the Diameter stack. The processing of any event that is not an incoming Sh message should be done as described for an application developed over the Base Protocol API (by implementing the processEvent() callback method).

Incoming Sh messages, however, are processed and decoded by the Diameter stack before they are delivered to one of the dedicated methods of the user-registered DiameterShListener instance, as described below.

Receiving Sh messages

All incoming messages that comply with the Sh syntax are decoded by the Diameter stack, and delivered to the suitable DiameterShListener method. The processEvent()) method handles only events and messages that are not known as Sh messages.

The example below shows the complete list of DiameterShListener interface’s callback functions. The userDataRequestReceived() callback implementation is taken from DiamShServer.java, and the userDataAnswerReceived() callback implementation is taken from DiamShClient.java

public void profileUpdateRequestReceived(
	String userIdentity, 
	String userData, 
	DiameterMessageEvent PUR){}
	
public void profileUpdateAnswerReceived(
	String resultCode, 
	DiameterMessageEvent PUA){}
	
public void pushNotificationRequestReceived(
	String userIdentity, 
	String userData, 
	DiameterMessageEvent PNR){}
	
public void pushNotificationAnswerReceived(
	String resultCode, 
	DiameterMessageEvent PNA){}
	
public void subscribeNotificationRequestReceived(
	String userIdentity, 
	String dataReference, 
	String subsReqType, 
	String serviceIndication, 
	String serverName, 
	DiameterMessageEvent SNR){}
	
public void subscribeNotificationAnswerReceived(
	String resultCode, 
	DiameterMessageEvent SNA){}
	
// The userDataRequestReceived method is used 
// on the server side (HSS)
// In this example the AS requests the 
// IMS USER STATE for user sip:john.doe@hp.com
// The HSS answers with a success resultCode 
// and the IMS USER STATE 

public void userDataRequestReceived(String userIdentity, 
	String dataReference, 
	String requestedDomain,
	String currentLocation, 
	String serviceIndication, 
	String serverName, 
	DiameterMessageEvent UDR) 
{
	System.out.println("Sh UDR received: "+
		UDR.getDiameterMessage().toString() );
			
	//create UDA message including the user reigstration information
	// the user data contains the IMS public Id of the user and its
	// registration status (1 = Registered)
	String userData = 
	"<?xml version=\"1.0\" encoding=\"UTF-8\"?>			\n" +
	"<Sh-Data xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance \n" +
	"xsi:noNamespaceSchemaLocation=\"ShDataType_Rel7.xsd\"> 	\n" +
	"<PublicIdentifiers> 						\n" +
	"	<IMSPublicIdentity> 					\n" +
	"		sip:john.doe@hp.com 				\n" +
	"	</IMSPublicIdentity> 					\n" +
	"</PublicIdentifiers> 						\n" +
	"<Sh-IMS-Data> 							\n" +
	"	<IMSUserState> 						\n" +
	"		1 						\n" +
	"	</IMSUserState> 					\n" +
	"</Sh-IMS-Data> 						\n" +
	"</Sh-Data>							";
			
	//Get the provider that generated this event 
	DiameterShProvider theShProviderForThisEvent =
		(DiameterShProvider) UDR.getSource();
	//Create the UDA, with Result-Code AVP = DIAMETER_SUCCESS
	DiameterShMessageFactory myShMessageFactory = 
		myStack.getDiameterShMessageFactory() ;
	DiameterMessage myUDA = 
	myShMessageFactory.createUserDataAnswer(
		DiameterShMessageFactory.DIAMETER_SUCCESS,
		userData);
			
	// Get the session Id from the incoming message 
	// and copy it to the answer
	myUDA.setSessionIdAVPValue
	  (UDR.getDiameterMessage().getSessionIdAVPValue());
	// Display and send the UDA message
	System.out.println("Server sending UDA :\n"+myUDA);
	theShProviderForThisEvent.sendMessage(myUDA);
}
	
public void userDataAnswerReceived(
String resultCode, 
String userData, 
DiameterMessageEvent UDA) 
{
	System.out.println((String) UDA.getDiameterMessage().toString() );
}

All callback methods must be implemented whatever the application, despite request related callbacks are applicable to HSS (server) and answer related callbacks are relevant only for the AS (client).

For ease of development, all DiameterShListener message reception callbacks provide the most-used AVPs as String type objects.

For more details, you can have a look at the Java source files available here: DiamBaseClient.java, DiamBaseServer.java