Skip Headers
Oracle® Communications Converged Application Server Developer's Guide
Release 5.1

Part Number E27707-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
PDF · Mobi · ePub

25 Creating Instant Messaging and Rich Media Services

Converged Application Server provides APIs that allow you to create rich messaging and media services for subscribers. This chapter describes the APIs provided by the Service Foundation Toolkit (SFT) that can be used to create Instant Message (IM) servers. The high level APIs abstract the protocol level details of SIP, IMS, and MSRP (and their inherent complexity), simplifying development of IM services.

About Rich Communication Services

Rich Communication Suite (RCS) provides rich messaging and media services for subscribers. The specification includes support for RCS-e (“e” for enhanced), which introduces IMS voice sessions (VoIP/VoLTE) that can be enriched for IM and chat, file transfer, and image sharing. RCS-e is designed to lower the entry barrier for RCS by providing operators and developers with a framework in which to deploy RCS functionality without needing to implement the full RCS profiles.

Converged Application Server provides APIs that can be used to create RCS-e compliant Instant Message (IM) servers. The high level APIs abstract the protocol level details of SIP, IMS, and MSRP (and their inherent complexity), simplifying development of RCS-e services.

Discovering Device Capability

The capability discovery process in RCS-e is handled using SIP OPTIONS and is the process by which a user is able to understand what RCS-e services are available on another user's equipment. In comparison to RCS, which only has feature tags for Image and Video Share, there are several more feature tags that are possible with RCS-e. The feature tags are sent in the Accept-Contact header of the SIP OPTIONS message by the requesting user equipment. The responding user equipment sends the response in the Contact header of the 200 OK message.

Figure 25-1 shows the RCS-e capabilities exchange signalling process.

Figure 25-1 Capability Discovery Call Flow

Surrounding text describes Figure 25-1 .
  1. End-user A, using device A, sends a SIP REGISTER request to the IMS core network.

  2. The IMS core responds with a SIP 200 OK to the SIP REGISTER request. At this point, User A restarts its registration timer.

  3. User A sends a SIP PUBLISH message with its capabilities to the IMS core.

  4. The IMS core responds with a SIP 200 OK.

  5. When User A decides that they wish to exchange device capabilities with User B, their device (user equipment) sends a SIP OPTIONS request to the IMS core.

  6. The IMS core routes the SIP OPTIONS request to User B.

  7. User B responds to User A with an SIP 200 OK message, containing the capabilities of User B's device.

If the terminating user has multiple devices, the terminating network applies a SIP-AS that sends multiple OPTIONS AS to each device, and aggregates the capabilities into a single OPTIONS response back to the user that sent the OPTIONS request.

About the Capability Discovery Interfaces

Capability discovery uses the following event types in the @CommunicationEvent annotation in the com.oracle.sft.api.bean package. For more information on these interfaces and their usage, refer to the Converged Application Server API Reference.

Table 25-1 @CommunicationEvent Event Types for Capability Discovery

Event Type Description

QUERIED

Specifies that the query process has returned a response, and can be appropriately handled.

QUERYING

Specifies that the process of querying (such as querying for device capabilities) is started.


Capability discovery uses of the following interfaces in the com.oracle.sft.api package. For more information on these interfaces and their usage, refer to the Converged Application Server API Reference.

Table 25-2 Capability Discovery Interfaces

Class Description

QueryInteraction

Queries for a message exchange (or interaction) between two user agents—such as SIP OPTIONS—via the AS.

QueryInteraction extends the Interaction interface.

Capability

Represents the data structure of the RCS-e capabilities.

CapabilityMessage

Allows the application to process the incoming SIP OPTIONS 200 OK message with either a QUERYING or QUERIED event, and represents the capability between participants in a QueryInteraction message exchange.

CapabilityMessage extends the Message interface.


Using the Capability Discovery Interfaces

The following sections illustrate the use of the QueryInteraction and CapabilityMessage interfaces.

Example 25-1 queries for the capabilities of a device by sending SIP OPTIONS, which allows a UA to query another UA or proxy server for its capabilities. QueryInteraction gets the context of the communication via the CommunicationContext interface's getCommunication()method.

The CapabilityMessage interface makes a call to the @CommunicationContext interface's getMessage() method, which passes the SIP OPTIONS message from the current communication session to the optionsMsg object variable.

Example 25-1 Querying to Determine Device Capabilities

@CommunicationEvent(type = CommunicationEvent.Type.QUERYING )
 void handleOptions() {
  // Retrieve SIP message exchange information from CommunicationContext.
  QueryInteraction ui = (QueryInteraction)ctx.getCommunication();
  CapabilityMessage optionMsg = (CapabilityMessage)ctx.getMessage();

Upon receiving the user's capabilities via SIP OPTIONS, you can use the Capability interface's getCapabilites() method to retrieve the capabilities of the user's equipment. Example 25-2 retrieves the user's contact capabilities, and then accepts them using the getAvailableCapabilities() method.

Example 25-2 Check If User Is Registered and RCS-e Capable

boolean isRegistered = true;
  boolean isRcseEnabled = true;
 
  if ( isRegistered && isRcseEnabled ) {
     // Get the contact capabilities and accept-accept capability
     Capability senderCapability = optionMsg.getCapabilities();
     Capability senderAcceptedCapability = optionMsg.getAvailableCapabilities();
    

If the application is functioning as a User Agent Client (UAC), the application responds with SIP 200 OK message and its RCS-e capabilities. Example 25-3 illustrates how a response message is created.

Example 25-3 Client RCS-e Capability Response

...
@Context CommunicationService service;
...
Capability myCapability = service.createCapability();

List<Feature> myRcse = new ArrayList<RcseFeature> ();
myRcse.add(Feature.RCSE_CHAT);
myRcse.add(Feature.RCSE_FT);
myRcse.add(Feature.VIDEO_SHARE_3GPP);
myRcse.add(Feature.RCSE_IMAGE_SHARE);
myCapability.setFeatures(myRcse);

optionMsg.consume(myCapability);
...

Example 25-4 shows a CommunicationBean in which Converged Application Server acts as both a User Agent Client (UAC) and User Agent Server (UAS). The CommunicationBean in this example performs the following functions:

  • The SIP OPTIONS message from the requesting user (User A) carries the capability tags in both the Contact and Accept-Contact header.

  • The SIP 200 OK response from a receiving user carries the capability tags in the Contact header.

  • If a receiving user is not registered, User A receives a SIP 480 TEMPORARILY UNAVAILABLE or SIP 408 REQUEST TIMEOUT response.

  • If a receiving user is not provisioned to use RCS-e, User A receives a 404 NOT FOUND response.

Example 25-4 Capability Discovery Using a UAC and UAS

@CommunicationBean
public class MyCommunicationBean {
 @Context CommunicationSession session;
 @Context CommunicationContext ctx;
 @Context CommunicationService service;
 
 @CommunicationEvent(type = CommunicationEvent.Type.QUERYING )
 void handleOptions() {
  // Retrieve option information from CommunicationContext.
  QueryInteraction ui = (QueryInteraction)ctx.getCommunication();
  CapabilityMessage optionMsg = (CapabilityMessage)ctx.getMessage();
  
  /** The application checks whether the receiver is registered, and if 
  *   they are RCS-e enabled.

  boolean isRegistered = true;
  boolean isRcseEnabled = true;
  
 
  if ( isRegistered && isRcseEnabled ) {
     // Get the contact capabilities and accept the capability
     Capability senderCapability = optionMsg.getCapabilities();
     Capability senderAcceptedCapability = optionMsg.getAvailableCapabilities();
     
/** The application acts as a UAS, forwarding the SIP OPTIONS message by default
 *  When acting as a UAC, the application responds with SIP 200 OK with its RCS-e features.
*/
     Capability myCapability = service.createCapability();
     
     List<Feature> myRcse = new ArrayList<RcseFeature> ();
     myRcse.add(Feature.RCSE_CHAT);
     myRcse.add(Feature.RCSE_FT);
     myRcse.add(Feature.VIDEO_SHARE_3GPP);
     myRcse.add(Feature.RCSE_IMAGE_SHARE);
     myCapability.setFeatures(myRcse);
     
     optionMsg.consume(myCapability);
      
     ui.end();
     }else if (!isRegistered ){
        optionMsg.reject(Reason.NOT_AVAILABLE); 
        ui.end();
     }else if (!isRcseEnabled ){
        optionMsg.reject(Reason.NOT_FOUND);
        ui.end();
    }
 }
 
/** On receiving a SIP 200 OK response in the SIP Options header, the application gets 
*   the received user's capabilites, then forwards the SIP 200 OK or ends the SIP dialog.
*/   
  @CommunicationEvent(type = CommunicationEvent.Type.QUERIED )
  void handleOptionsResponse() {
      
    QueryInteraction ui = (QueryInteraction)ctx.getCommunication();
    CapabilityMessage optionMsg = (CapabilityMessage)ctx.getMessage();
    Capability myCapability = optionMsg.getCapabilities(); 
    
    /** If the application is acting as a UAS, it does nothing, and the 
    *   response is forwarded by default. 
    *   If the application is acting as a UAC, it terminates communication. 
    
    ui.end();
}

Using In-dialog, SIP Options-based Capability Discovery

Using SIP OPTIONS, an application can discover service capabilities before establishing a communication session. This discovery mechanism allows users to determine what services are available prior to establishing a call or IM session. A SIP OPTIONS message is sent in-dialog during the establishment of a voice call or IM session to obtain the real-time capabilities of the service. Converged Application Server supports in-dialog SIP OPTIONS-based capability discovery and capability update during 1-to-1 chat and 1-to-1 call.

Note:

SFT provides APIs to obtain service capabilities from a received SIP OPTIONS 200 OK message, but does not provide APIs to create or send in-dialog SIP OPTIONS messages.

Example 25-5 illustrates how to retrieve the SIP OPTIONS message containing service capabilities information from the CommunicationContext interface using CapabilityMessage.

Example 25-5 In-Dialog SIP OPTIONS-based Capability Discovery

@CommunicationBean
public class MyCommunicationBean {
 @Context CommunicationSession session;
 @Context CommunicationContext ctx;
 @Context CommunicationService service;
 
 @CommunicationEvent(type = CommunicationEvent.Type.QUERYING )
 void handleOptions() {
  //Get SIP OPTION information from CommunicationContext.
  Conversation ui = (Conversation)ctx.getCommunication();
  CapabilityMessage optionMsg = (CapabilityMessage)ctx.getMessage();
  
  //Receive the contact and accept-accept capabilities 
     Capability senderCapability = optionMsg.getCapabilities();
     Capability senderAcceptedCapability = optionMsg.getAcceptCapabilities();
     
   }
 
//Receive 200 OK response via SIP OPTIONS. 
//The application gets the receiving user's capability, then forwards this 200 OK  
//or terminates this SIP dialog. 
  @CommunicationEvent(type = CommunicationEvent.Type.QUERIED )
  void handleOptionsResponse() {
      
    Conversation ui = (Conversation )ctx.getCommunication();
    CapabilityMessage optionMsg = (CapabilityMessage)ctx.getMessage();
    Capability myCapability = optionMsg.getCapabilities(); 
  }
...

Using End User Confirmation Request

End User Confirmation Request (EUCR) is a mechanism by which an application server communicates with a user about a service, and queries for confirmation as to what actions to take. In the client device's user interface (UI) this might equate to a pop-up menu or similar UI element that the user can interact with to confirm or deny a specific service request.

The sequence of steps to perform a EUCR is as follows:

  1. The end user confirmation request is implemented using a SIP MESSAGE method containing an XML payload of type application/end-user-confirmation-request+xml that is sent by the application server to the end user's RCS-e client (for example, a mobile phone).

  2. Upon receipt of the SIP MESSAGE, the end user's device checks the P-Asserted-Identity of the incoming message, and matches it against the configured URI for the service, and extracts the request information from the XML payload body. A dialog or notification is displayed on the end user's device (UX dependant) displaying the confirmation request and any related information.

  3. The end user's confirmation response is encapsulated in an XML body with a payload of type application/end-user-confirmation-response+xml, and returned either in the SIP MESSAGE response back to the MNO, or in a new SIP MESSAGE.

    The information contained in the end user confirmation request is:

    • id: Unique identifier of the request.

    • type: Determines the behavior of the receiving device. The type can take one of the following two values:

      • volatile—the answer is returned in the SIP 200 OK response. If the SIP INFO message times out without end user input, the request is discarded.

      • persistent—the answer is returned in a new SIP MESSAGE request. The confirmation request does not time out.

    • pin: Determines whether a pin number is requested of the end user. It can take one of the following two values: true or false. If the attribute is not present it is considered false. Pin requests can be used to add a higher degree of confirmation authentication, and can be used to allow operations such as parental control or other security features.

    • Subject: Text to display within the notification, or as a dialog box title.

    • Text: Text to display within the body of the dialog box.

  4. (Optional) If the type of the confirmation request is persistent, the MNO can send an optional acknowledgement message of the transaction back to the user with a welcome message, an error message, or additional instructions. The acknowledgement message is encapsulated in an XML body with a payload of type application/end-user-confirmationack+ xml and returned in the SIP 200 OK body of the confirmation SIP MESSAGE.

    The end user confirmation response is:

    • id: Unique identifier of the request.

    • value: Specifies if the end user accepts or declines the request. It takes one of the following two values: accept or decline

    The information contained in the end user acknowledgement response is:

    • id: Unique identifier of the request.

    • status: with the end user confirmation. It can take one of the following two values: ok or error

    • Subject: Text to display within the notification, or as a dialog box title.

    • Text: Text to display within the body of the dialog box.

About the EUCR Interfaces

EUCR makes use of the following classes in the com.oracle.sft.api package. For more information on these interfaces and their usage, refer to the Converged Application Server API Reference.

Table 25-3 Interfaces for EUCR

Class Description

EndUserConfirmationData

Represents the data structure for the End User Confirmation Request, End User Confirmation Response, and End User Confirmation Acknowledgement messages.

EndUserConfirmationDisplay

Represents the Subject and Text message displayed on the end user client during EUCR exchange.

EndUserConfirmationMessage

The extended Message for EUCR exchange.

IMConversation

Represents a two party IM conversation. The application uses this communication type to send and receive messages. For EUCR, IMConversation provides the following methods:

  • createEndUserConfirmRequestMessage()

  • createEndUserConfirmResponseMessage()

CommunicationEvent

Specifies events pertaining to a Communication. Any method using this annotation is invoked when the CommunicationEvent of the specified type occurs. For EUCR, CommunicationEvent provides the following events:

  • CONFIRMATION_MESSAGEARRIVED

  • CONFIRMATION_RESPONDED

  • CONFIRMATION_FINISHED

CommunicationService

A utility class to create objects that are not related to a CommunicationSession, for example groups. For EUCR, CommunicationService provides the method: createEndUserConfirmationData()


Using EUCR in Response to a File Transfer

Example 25-6 shows the code to sends a EUCR in response to initiating a file transfer. If the user chooses to confirm the request, they will be charged an additional amount on their bill.

Example 25-6 EUCR In Response to a File Transfer

@CommunicationBean
public class MyCommunicationBean {
 
  @Context CommunicationSession session;
  @Context CommunicationContext ctx;
  @Context CommunicationService service;
 
  private boolean authorization = false;
  private Message origMsg;
  
  @CommunicationEvent(type=CommunicationEvent.Type.INITIALIZATION )
  void handleInit() {
     origMsg = ctx.getMessage();
     Interaction  ii = (Interaction ) ctx.getCommunication();
     if ( ii instanceof MSRPConversation){
       MSRPConversation MSRPConv = (MSRPConversation) ii; 
       Participant receiver = MSRPConv.getParticipant();
       Participant sender = MSRPConv.getInitiator ();
       IMConversation newIM = session.createIMConversation("imserver@example.com");
       newIM.addParticipant(sender.getName()); 
        /**
          * 
         EndUserConfirmationData request = service.createEndUserConfirmationData();
         request.setId("EucrTest1");
         request.setPinRequired(true);
         request.setBehaviour(Behaviour.Persistent );     
         
        // Constructor to create a new IMConversation, and send the EUCR.
         newIM.createEndUserConfirmationRequestMessage(request).send();
         
          EndUserConfirmationDisplay display;
          display =  request.createDisplayText("Extra Charge","Charing Conditions", "en");
          request.setCondition(display);
          
          display = request.createDisplayText("????,"0?1?/M", "ch");
          request.setCondition(display);
          
         try {
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
         if( !authorization){
           origMsg.reject(Reason.DECLINE);
           MSRPConv.end();
           
         }
         
     }  
  }
 
  //**
     * Handles SIP MESSAGE 200 OK containing the EUCR response is received by IMConversation
     * 
    @CommunicationEvent(type=CommunicationEvent.Type.CONFIRMATION_RESPONDED)
    void handleEUCResponseMessage() {
       
       IMConversation  IMConv = (IMConversation) ctx.getCommunication();
       byte[] content = ctx.getMessage().getContent().toString().getBytes();
       EndUserConfirmationMessage msg = (EndUserConfirmationMessage) ctx.getMessage();
       EndUserConfirmationData resp = msg.getData();
       EndUserConfirmationData ack = resp.createAcknowledgement();
       if ( resp.getAction().equalsIgnoreCase("accept")){
       resp.setAcknowledgement( resp.createDisplayText("Welcome", "Hello", "en"));
       msg.consume();
           this.authorization = true;
           IMConv.end();
       }else {
       resp.setAcknowledgement( resp.createDisplayText("Sorry", "Can Not Access", "en"));
       msg.consume()
           this.authorization = false;
           IMConv.end();
           
        }
   }
} 

Conferencing Using MSRP

Message Session Relay Protocol (MSRP) is a protocol for transmitting a series of related instant messages in the context of a session. Message sessions are treated like any other media stream when set up via a rendezvous or session creation protocol such as the Session Initiation Protocol (SIP). MSRP Sessions are defined in RFC 4975.

Using Instant Message Disposition Notification

To support store and forward status reporting and message disposition, RCS-e uses Instant Message Disposition Notification (IMDN) to request and forward dispositions of all exchanged messages. Converged Application Server supports Page Mode instant messaging, which uses the SIP method MESSAGE as defined in RFC 3428. Page Mode instant messaging establishes no sessions. Instant Message Disposition Notification (IMDN) is defined in RFC 5438.

Instant messages are constructed using the Common Presence and Instant Messaging (CPIM) message format defined in RFC 3862. Converged Application Server supports the following aspects of RFC 5438 when constructing Instant Messages in the CPIM message format:

Converged Application Server supports following aspects of RFC 5438 when constructing the IMDN:

Refer to RFC 5438 for more information on these aspects of creating IMDNs.

About the IMDN Interfaces

IMDN makes use of the following classes in the com.oracle.sft.api package. For more information on these interfaces and their usage, refer to the Converged Application Server API Reference.

Table 25-4 IMDN Interfaces

Class Description

CommonPresenceInstantMessage

The extension to TextMessage for message/CPIM format, you can use CommonPresenceInstantMessage to construct common IM messages using the CPIM format, IM message requesting disposition notifications, and IMDN messages.

DispositionContext

Represents the data carried in the Disposition message.

DispositionNotification

The data structure for disposition notification. You use this interface to construct and parse IMDN payloads.

CommunicationEvent

Specifies events pertaining to a Communication. Any method using this annotation is invoked when the CommunicationEvent of the specified type occurs. For IMDN, CommunicationEvent provides the following events:

  • MESSAGE_SUCCESS_RESONDED

  • MESSAGE_FAILUER_RESONDED

  • DISPOSITION_REQUEST_SUCCESS_RESPONDED

  • DISPOSITION_REQUEST_FAILURE_RESPONDED

IMConversation

Represents a two party IM conversation. The application uses this communication type to send and receive messages. For IMDN, IMConversation provides the createCommonPresenceInstantMessage() method to create CPIM messages.

IMConference

Represents a multi-party, Page Mode instant message session. For IMDN, IMConference provides the createCommonPresenceInstantMessage() method to create CPIM messages.


Creating an Instant Message with IMDN Request

Example 25-7 creates an instant message with an IMDN in the message header for a two-party IM conversation.

Example 25-7 Creating an Instant Message With an IMDN Request

public class CpimServlet extends HttpServlet{
/**
CommunicationSession session =
(CommunicationSession)request.getSession().getAttribute(CommunicationSession.NAME); 

CommunicationService service =            (CommunicationService)request.getSession().getAttribute(CommunicationService.NAME); 
        java.io.PrintWriter out = response.getWriter();
        String party1 = request.getParameter("Party1");
        String party2 = request.getParameter("Party2"); 
        try {
          
           out.println("<html>");
           
          IMConversation conv  = session.createIMConversation(party1);
          conv.addParticipant(party2);
          
          CommonPresenceInstantMessage cpimReq = conv.createCommonPresenceInstantMessage ();
          cpimReq.setHeader(Header.Subject.toString(), "imdn test");
          DispositionContext disposCxt = 
          cpimReq.buildDispositionContext("hello world!", "text/plain");
          
          disposCxt.setDispositionRequest(RequestType.negative_delivery);
          disposCxt.setDispositionRequest(RequestType.processing);
          cpimReq.setDispositionContext(disposCxt);
          cpimReq.send();
      }

Creating an IMDN With CommunicationBean

Example 25-8 creates a CommunicationBean that acts as an intermediary server (a store-and-forward server) for a two-party conversation using the IMConversation interface. The actual IMDN message is not stored, but content disposition is performed so that Store/Forward information status reporting can be done according to RFC 5438.

Example 25-8 Creating an IMDN with CommunicationBean

@ServiceAttributes(domainName = "example.com")
@CommunicationBean 
public class CpimBean {
 
  @Context CommunicationSession session;
  @Context CommunicationContext ctx;
  @Context CommunicationService service;
  
  private DispositionContext aggregationContext;  
  @CommunicationEvent(type=CommunicationEvent.Type.MESSAGEARRIVED)
  void handleMessage ( ){
    
   //** If the message contains a disposition request, the server forwards the message 
      * to the recipient. If the message is sent to multiple recipients, the server      
      * behaves as specifed RFC 5365.
   /*
              
    IMConversation conv = (IMConversation) ctx.getCommunication();
    CommonPresenceInstantMessage msg = (CommonPresenceInstantMessage)conv.getMessage(); 
    
         DispositionContext getImdns = msg.getDispositionContext();
         if (getImdns == null ){
           System.out.println("Received CPIM message ");
          
         }
         
         if (getImdns != null && getImdns.getDispositionNotifications()== null){
           System.out.println("Received Disposition Request ");
           msg.consume();
           CommonPresenceInstantMessage imdnMsg = conv .createCommonPresenceInstantMessage();
           imdnMsg.setDispositionContext( getImdns());
           imdnMsg.send();
      
         } 
    
    }
 
  @CommunicationEvent(type=CommunicationEvent.Type.DISPOSITION_REQUEST_SUCCESS_RESPONDED)
  void handleImdnSuccessResponse ( ){
     
    IMConversation conv = (IMConversation) ctx.getCommunication();
    CommonPresenceInstantMessage msg = (CommonPresenceInstantMessage )conv.getMessage( ); 
    DispositionContext origCxt = msg.getDispositionContext();
    CommonPresenceInstantMessage newMsg = conv.createCommonPresenceInstantMessage (); 
    if ( origCxt.isDispositionRequest( RequestType.positive_delivery ){
       newMsg.buildDispositionContext(msg,Type.delivery ,Status.delivered);
    }
   if(imdnMsg.getDispositionContext()!= null && imdnMsg.getDispositionContext().getDispositionNotifications() != null )   
       newMsg.send( conv.getParticipant() );
  }
  @CommunicationEvent(type=CommunicationEvent.Type.DISPOSITION_REQUEST_FAILURE_RESONDED)
  void handleImdnFailureResponse( ){
    
    IMConversation conv = (IMConversation) ctx.getCommunication();
    CommonPresenceInstantMessage msg = (CommonPresenceInstantMessage )conv.getMessage( ); 
    DispositionContext origCxt = msg.getDispositionContext();
    CommonPresenceInstantMessage newMsg = conv.createCommonPresenceInstantMessage (); 
    if ( origCxt.isDispositionRequest( RequestType.negative_delivery ){
          
       newMsg.buildDispositionContext(msg, Type.delivery ,Status.failed);
    }
    
    // If the message is stored,
    if ( origCxt.isDispositionRequest( RequestType.processing ){
       newMsg.buildDispositionContext(nsg,Type.processing ,Status.stored);
    }
     if(imdnMsg.getDispositionContext()!= null && imdnMsg.getDispositionContext().getDispositionNotifications() != null )
              newMsg.send( conv.getParticipant() );
 
   }
 
   @CommunicationEvent(type=CommunicationEvent.Type.MESSAGE_SUCCESS_RESPONDED)
    void handleResponse() {
     System.out.println(" Enter MESSAGE_SUCCESS_RESONDED event "); 
     
     IMConversation  conv = (IMConversation) ctx.getCommunication();
     CommonPresenceInstantMessage msg = (CommonPresenceInstantMessage)ctx.getMessage();
     if (msg!= null && msg.getDispositionContext()!= null && msg.getDispositionContext().getDispositionNotifications()!=null ){
       System.out.println(" Disposition Notification Message is Responed ");
       conv.end();
     }
    }
    
    @CommunicationEvent(type=CommunicationEvent.Type.MESSAGE_FAILURE_RESPONDED)
    void handleErrorResponse() {
     System.out.println(" Enter MMESSAGE_FAILUER_RESPONDED event "); 
    }