org.cafesip.sipunit
Class PresenceNotifySender

java.lang.Object
  extended by org.cafesip.sipunit.PresenceNotifySender
All Implemented Interfaces:
MessageListener, RequestListener
Direct Known Subclasses:
ReferNotifySender

public class PresenceNotifySender
extends java.lang.Object
implements MessageListener

The primary purpose of this class is as a test utility, to verify other UA's NOTIFY reception processing. When instantiated, an object of this class listens for a SUBSCRIBE message. After the calling program has sent a SUBSCRIBE message to this object's uri, it can call this object's processSubscribe() to receive and process the SUBSCRIBE and send a response. After that, this object sends a NOTIFY message on that subscription each time method sendNotify() is called, with the given content body. This class can listen for and show the response to a given sent NOTIFY message. It can receive and process multiple SUBSCRIBE messages for a subscription.


Constructor Summary
PresenceNotifySender(SipPhone userb)
          A constructor for this class.
 
Method Summary
 javax.sip.message.Request addNotifyHeaders(javax.sip.message.Request req, java.lang.String toUser, java.lang.String toDomain, java.lang.String subscriptionState, java.lang.String termReason, java.lang.String body, int timeLeft)
          This method adds each of the given parameters, if not null, to the given NOTIFY Request parameter which just contains the request line (created from a string).
 void dispose()
          Dispose of this object (but not the stack given to it).
 java.util.ArrayList<SipRequest> getAllReceivedRequests()
          This method returns all the requests received by this object and can be called directly by a test program.
 java.util.ArrayList<SipResponse> getAllReceivedResponses()
          This method returns all the responses received by this object and can be called directly by a test program.
 javax.sip.Dialog getDialog()
           
 java.lang.String getErrorMessage()
          Returns the error message, if any, associated with the last operation.
 SipRequest getLastReceivedRequest()
          This method returns the last request received by this object and can be called directly by a test program.
 SipResponse getLastReceivedResponse()
          This method returns the last response received by this object and can be called directly by a test program.
 javax.sip.message.Request getLastSentNotify()
          Returns the NOTIFY request that was last sent, or null if none has ever been sent.
 boolean needAuthorization(javax.sip.ResponseEvent event)
          Called to find out if a sent NOTIFY was challenged.
 void processEvent(java.util.EventObject event)
          For internal SipUnit use only.
 boolean processSubscribe()
          This method waits for up to 10 seconds to receive a SUBSCRIBE and if received, it sends an OK response.
 boolean processSubscribe(long timeout, int statusCode, java.lang.String reasonPhrase)
          This method starts a thread that waits for up to 'timeout' milliseconds to receive a SUBSCRIBE and if received, it sends a response with 'statusCode' and 'reasonPhrase' (if not null).
 boolean processSubscribe(long timeout, int statusCode, java.lang.String reasonPhrase, int overrideDuration, javax.sip.header.EventHeader overrideEvent)
          Same as the other processSubscribe() except allows for a couple of overrides for testing error handling by the far end outbound SUBSCRIBE side: (a) this method takes a duration for overriding what would normally/correctly be sent back in the response (which is the same as what was received in the SUBSCRIBE request or default 3600 if none was received).
 boolean register(Credential credential)
          This method registers this notify sender as a UA with the proxy/registrar used to create the SipPhone passed to this object's contructor.
 SipTransaction resendWithAuthorization(javax.sip.ResponseEvent event)
          This method resends a NOTIFY statefully and with required authorization headers.
 boolean sendNotify(javax.sip.message.Request req, boolean viaProxy)
          This method sends the given request to the subscriber.
 boolean sendNotify(java.lang.String subscriptionState, java.lang.String termReason, java.lang.String body, int timeLeft, boolean viaProxy)
          This method creates a NOTIFY message using the given parameters and sends it to the subscriber.
 boolean sendNotify(java.lang.String subscriptionState, java.lang.String termReason, java.lang.String body, int timeLeft, javax.sip.header.EventHeader eventHdr, javax.sip.header.SubscriptionStateHeader ssHdr, javax.sip.header.AcceptHeader accHdr, javax.sip.header.ContentTypeHeader ctHdr, boolean viaProxy)
          This method creates a NOTIFY message using the given parameters and sends it to the subscriber.
 SipTransaction sendStatefulNotify(javax.sip.message.Request req, boolean viaProxy)
          This method sends the given request to the subscriber.
 void setDialog(javax.sip.Dialog dialog)
           
 java.util.EventObject waitResponse(SipTransaction trans, long timeout)
          The waitResponse() method waits for a response to a previously sent transactional request message.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

PresenceNotifySender

public PresenceNotifySender(SipPhone userb)
A constructor for this class. This object immediately starts listening for a SUBSCRIBE request.

Parameters:
userb - SipPhone object to use for messaging.
Throws:
java.lang.Exception - If there's a problem
Method Detail

dispose

public void dispose()
Dispose of this object (but not the stack given to it).


processSubscribe

public boolean processSubscribe()
This method waits for up to 10 seconds to receive a SUBSCRIBE and if received, it sends an OK response.

Returns:
true if SUBSCRIBE received and response sending was successful, false otherwise (call getErrorMessage() for details).

processSubscribe

public boolean processSubscribe(long timeout,
                                int statusCode,
                                java.lang.String reasonPhrase)
This method starts a thread that waits for up to 'timeout' milliseconds to receive a SUBSCRIBE and if received, it sends a response with 'statusCode' and 'reasonPhrase' (if not null). This method waits 500 ms before returning to allow the thread to get started and begin waiting for an incoming SUBSCRIBE. This method adds 500ms to the given timeout to account for this delay.

Parameters:
timeout - - number of milliseconds to wait for the SUBSCRIBE
statusCode - - use in the response to the SUBSCRIBE
reasonPhrase - - if not null, use in the SUBSCRIBE response
Returns:
true if the thread got started OK.

processSubscribe

public boolean processSubscribe(long timeout,
                                int statusCode,
                                java.lang.String reasonPhrase,
                                int overrideDuration,
                                javax.sip.header.EventHeader overrideEvent)
Same as the other processSubscribe() except allows for a couple of overrides for testing error handling by the far end outbound SUBSCRIBE side: (a) this method takes a duration for overriding what would normally/correctly be sent back in the response (which is the same as what was received in the SUBSCRIBE request or default 3600 if none was received). Observed if >= 0. (b) this method takes an EventHeader for overriding what would normally/correctly be sent back in the respone (same as what was received in the request).


sendNotify

public boolean sendNotify(java.lang.String subscriptionState,
                          java.lang.String termReason,
                          java.lang.String body,
                          int timeLeft,
                          boolean viaProxy)
This method creates a NOTIFY message using the given parameters and sends it to the subscriber. The request will be resent if challenged. Use this method only if you have previously called processSubscribe(). Use this method if you don't care about checking the response to the sent NOTIFY, otherwise use sendStatefulNotify().

Parameters:
subscriptionState - - String to use as the subscription state.
termReason - - used only when subscriptionState = TERMINATED.
body - - NOTIFY body to put in the message
timeLeft - - expiry in seconds to put in the NOTIFY message (used only when subscriptionState = ACTIVE or PENDING).
viaProxy - If true, send the message to the proxy. In this case a Route header will be added. Else send the message as is.
Returns:
true if successful, false otherwise (call getErrorMessage() for details).

sendNotify

public boolean sendNotify(java.lang.String subscriptionState,
                          java.lang.String termReason,
                          java.lang.String body,
                          int timeLeft,
                          javax.sip.header.EventHeader eventHdr,
                          javax.sip.header.SubscriptionStateHeader ssHdr,
                          javax.sip.header.AcceptHeader accHdr,
                          javax.sip.header.ContentTypeHeader ctHdr,
                          boolean viaProxy)
This method creates a NOTIFY message using the given parameters and sends it to the subscriber. Knowledge of JAIN-SIP API headers is required. The request will be resent if challenged. Use this method only if you have previously called processSubscribe(). Use this method if you don't care about checking the response to the sent NOTIFY, otherwise use sendStatefulNotify().

Parameters:
subscriptionState - - String to use as the subscription state. Overridden by sshdr.
termReason - - used only when subscriptionState = TERMINATED. Overridden by sshdr.
body - - NOTIFY body to put in the message
timeLeft - - expiry in seconds to put in the NOTIFY subscription state header (only when subscriptionState = ACTIVE or PENDING), unless the timeLeft value is -1 in which case don't include expires information in the subscription state header. Overridden by sshdr.
eventHdr - - if not null, use this event header in the NOTIFY message
ssHdr - - if not null, use this subscription state header in the NOTIFY message instead of building one from other parameters given.
accHdr - - if not null, use this accept header. Otherwise build the default package one (pidf+xml).
ctHdr - - if not null, use this content type header. Otherwise build the default package one (pidf+xml).
viaProxy - If true, send the message to the proxy. In this case a Route header will be added. Else send the message as is.
Returns:
true if successful, false otherwise (call getErrorMessage() for details).

addNotifyHeaders

public javax.sip.message.Request addNotifyHeaders(javax.sip.message.Request req,
                                                  java.lang.String toUser,
                                                  java.lang.String toDomain,
                                                  java.lang.String subscriptionState,
                                                  java.lang.String termReason,
                                                  java.lang.String body,
                                                  int timeLeft)
This method adds each of the given parameters, if not null, to the given NOTIFY Request parameter which just contains the request line (created from a string). It is for the purpose of building a NOTIFY message to send out. If a dialog is associated with this object (ie, a request has been previously received), this method takes the information from there to create headers for the null parameters passed in, else this method makes up the header content.

Parameters:
req - Request parameter which just contains the request line
toUser - Used to create the 'To' header address - user part
toDomain - Used to create the 'To' header address - host part of sip URI
subscriptionState - active, pending, or terminated (SubscriptionStateHeader constant)
termReason - any string
body - the entire content as a string
timeLeft - number of seconds to put in the NOTIFY
Returns:
the modified request

sendNotify

public boolean sendNotify(javax.sip.message.Request req,
                          boolean viaProxy)
This method sends the given request to the subscriber. Knowledge of JAIN-SIP API headers is required. The request will be resent if challenged. Use this method only if you have previously called processSubscribe(). Use this method if you don't care about checking the response to the sent NOTIFY, otherwise use sendStatefulNotify().

Parameters:
req - javax.sip.message.Request to send.
viaProxy - If true, send the message to the proxy. In this case a Route header will be added. Else send the message as is.
Returns:
true if successful, false otherwise (call getErrorMessage() for details).

sendStatefulNotify

public SipTransaction sendStatefulNotify(javax.sip.message.Request req,
                                         boolean viaProxy)
This method sends the given request to the subscriber. Use this method when you want to see the response received in reply to the NOTIFY sent by this method. Authentication challenges received in reponse to the sent request are not automatically handled by this class - the caller will have to check for and handle it (TODO, provide a method that does like processRespons() for the caller to use). Knowledge of JAIN-SIP API headers is required to use this method. You may call this method whether or not this object has received a request (ie, whether or not you have previously called processSubscribe() on this object.) You may subsequently call waitResponse() to check the response returned by the far end.

Parameters:
req - javax.sip.message.Request to send.
viaProxy - If true, send the message to the proxy. In this case a Route header will be added. Else send the message as is.
Returns:
A SipTransaction object if the message was sent successfully, null otherwise. The calling program doesn't need to do anything with the returned SipTransaction other than pass it in to a subsequent call to waitResponse().

waitResponse

public java.util.EventObject waitResponse(SipTransaction trans,
                                          long timeout)
The waitResponse() method waits for a response to a previously sent transactional request message. Call this method after calling sendStatefulNotify(). This method blocks until one of the following occurs: 1) A javax.sip.ResponseEvent is received. This is the object returned by this method. 2) A javax.sip.TimeoutEvent is received. This is the object returned by this method. 3) The wait timeout period specified by the parameter to this method expires. Null is returned in this case. 4) An error occurs. Null is returned in this case. Note that this method can be called repeatedly upon receipt of provisional response message(s).

Parameters:
trans - The SipTransaction object associated with the sent request. This is the object returned by sendStatefulNotify().
timeout - The maximum amount of time to wait, in milliseconds. Use a value of 0 to wait indefinitely.
Returns:
A javax.sip.ResponseEvent, javax.sip.TimeoutEvent, or null in the case of wait timeout or error. If null, call getReturnCode() and/or getErrorMessage() and, if applicable, getException() for further diagnostics.

register

public boolean register(Credential credential)
This method registers this notify sender as a UA with the proxy/registrar used to create the SipPhone passed to this object's contructor.

Parameters:
credential - authentication information matching that at the server
Returns:
true if registration is successful, false otherwise. If false, call getErrorMessage() to find out why.

getErrorMessage

public java.lang.String getErrorMessage()
Returns the error message, if any, associated with the last operation.

Returns:
A String describing the error that occurred during the last operation, or an empty string ("") if there was no error.

getLastSentNotify

public javax.sip.message.Request getLastSentNotify()
Returns the NOTIFY request that was last sent, or null if none has ever been sent.

Returns:
javax.sip.message.Request last sent.

getAllReceivedResponses

public java.util.ArrayList<SipResponse> getAllReceivedResponses()
Description copied from interface: MessageListener
This method returns all the responses received by this object and can be called directly by a test program.

Specified by:
getAllReceivedResponses in interface MessageListener
Returns:
ArrayList of zero or more SipResponse objects.
See Also:
MessageListener.getLastReceivedResponse()

getAllReceivedRequests

public java.util.ArrayList<SipRequest> getAllReceivedRequests()
Description copied from interface: MessageListener
This method returns all the requests received by this object and can be called directly by a test program.

Specified by:
getAllReceivedRequests in interface MessageListener
Returns:
ArrayList of zero or more SipRequest objects.
See Also:
MessageListener.getLastReceivedRequest()

getLastReceivedRequest

public SipRequest getLastReceivedRequest()
Description copied from interface: MessageListener
This method returns the last request received by this object and can be called directly by a test program.

Specified by:
getLastReceivedRequest in interface MessageListener
Returns:
A SipRequest object representing the last request message received, or null if none has been received.
See Also:
MessageListener.getAllReceivedRequests()

getLastReceivedResponse

public SipResponse getLastReceivedResponse()
Description copied from interface: MessageListener
This method returns the last response received by this object and can be called directly by a test program.

Specified by:
getLastReceivedResponse in interface MessageListener
Returns:
A SipResponse object representing the last response message received, or null if none has been received.
See Also:
MessageListener.getAllReceivedResponses()

processEvent

public void processEvent(java.util.EventObject event)
Description copied from interface: RequestListener
For internal SipUnit use only.

Specified by:
processEvent in interface RequestListener
Parameters:
event - Event received.

needAuthorization

public boolean needAuthorization(javax.sip.ResponseEvent event)
Called to find out if a sent NOTIFY was challenged. See related method resendWithAuthorization().

Parameters:
event - object returned by waitResponse().
Returns:
true if response status is UNAUTHORIZED or PROXY_AUTHENTICATION_REQUIRED, false otherwise.

resendWithAuthorization

public SipTransaction resendWithAuthorization(javax.sip.ResponseEvent event)
This method resends a NOTIFY statefully and with required authorization headers. Call it after you find out that authorization is required by calling method needAuthorization(). Example testcode usage (this object is "sender"): // get the response, trans is SipTransaction object EventObject event = sender.waitResponse(trans, 2000); assertNotNull(sender.getErrorMessage(), event); if (event instanceof TimeoutEvent) { fail("Event Timeout received by far end while waiting for NOTIFY response"); } assertTrue("Expected auth challenge", sender .needAuthorization((ResponseEvent) event)); trans = sender.resendWithAuthorization((ResponseEvent) event); assertNotNull(sender.getErrorMessage(), trans); // get the next response event = sender.waitResponse(trans, 2000); etc.

Parameters:
event - object returned by waitResponse()
Returns:
SipTransaction for internal use, only needs to be passed to waitResponse().

getDialog

public javax.sip.Dialog getDialog()
Returns:
Returns the dialog.

setDialog

public void setDialog(javax.sip.Dialog dialog)
Parameters:
dialog - The dialog to set.


http://www.cafesip.org