Allows multiple processors for one and the same method in ProtocolProviderServiceSipImpl and stops dispatching a specific event as soon as a method processor declares that the event in question has been handled.

cusax-fix
Lyubomir Marinov 18 years ago
parent 5f556b1d12
commit 504fa02ae9

@ -25,7 +25,7 @@
* @author Emil Ivov
*/
public class ClientCapabilities
implements SipListener
implements MethodProcessor
{
private static Logger logger = Logger.getLogger(ClientCapabilities.class);
@ -48,7 +48,7 @@ public ClientCapabilities(ProtocolProviderServiceSipImpl protocolProvider)
{
this.provider = protocolProvider;
provider.registerMethodProcessor(Request.OPTIONS, this);
provider.addRegistrationStateChangeListener(new RegistrationListener());
}
@ -58,7 +58,7 @@ public ClientCapabilities(ProtocolProviderServiceSipImpl protocolProvider)
*
* @param requestEvent the incoming options request.
*/
public void processRequest(RequestEvent requestEvent)
public boolean processRequest(RequestEvent requestEvent)
{
Response optionsOK = null;
try
@ -101,7 +101,7 @@ public void processRequest(RequestEvent requestEvent)
{
//What else could we do apart from logging?
logger.warn("Failed to create an incoming OPTIONS request", ex);
return;
return false;
}
try
@ -120,58 +120,64 @@ public void processRequest(RequestEvent requestEvent)
{
//What else could we do apart from logging?
logger.warn("Failed to send an incoming OPTIONS request", ex);
return;
return false;
}
catch (SipException ex)
{
//What else could we do apart from logging?
logger.warn("Failed to send an incoming OPTIONS request", ex);
return;
return false;
}
return true;
}
/**
* ignore. don't needed.
* @param dialogTerminatedEvent unused
*/
public void processDialogTerminated(
public boolean processDialogTerminated(
DialogTerminatedEvent dialogTerminatedEvent)
{
return false;
}
/**
* ignore. don't needed.
* @param exceptionEvent unused
*/
public void processIOException(IOExceptionEvent exceptionEvent)
public boolean processIOException(IOExceptionEvent exceptionEvent)
{
return false;
}
/**
* ignore for the time being
* @param responseEvent unused
*/
public void processResponse(ResponseEvent responseEvent)
public boolean processResponse(ResponseEvent responseEvent)
{
return false;
}
/**
* ignore for the time being.
* @param timeoutEvent unused
*/
public void processTimeout(TimeoutEvent timeoutEvent)
public boolean processTimeout(TimeoutEvent timeoutEvent)
{
disconnect();
return true;
}
/**
* ignore for the time being.
* @param transactionTerminatedEvent unused
*/
public void processTransactionTerminated(
public boolean processTransactionTerminated(
TransactionTerminatedEvent transactionTerminatedEvent)
{
return false;
}
/**

@ -0,0 +1,114 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.sip;
import javax.sip.*;
/**
* Represents a processor of events with a specific method received in
* {@link ProtocolProviderServiceSipImpl} much like <code>SipListener</code> but
* with the addition of signaling whether the specified event was indeed handled
* in the processor and needs no further processing in other processors
* registered for the same method.
*
* @author Lubomir Marinov
*/
public interface MethodProcessor
{
/**
* Process an asynchronously reported DialogTerminatedEvent. When a dialog
* transitions to the Terminated state, the stack keeps no further records
* of the dialog. This notification can be used by applications to clean up
* any auxiliary data that is being maintained for the given dialog.
*
* @param dialogTerminatedEvent an event that indicates that the dialog has
* transitioned into the terminated state
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
boolean processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent);
/**
* Process an asynchronously reported IO Exception. Asynchronous IO
* Exceptions may occur as a result of errors during retransmission of
* requests. The transaction state machine requires to report IO Exceptions
* to the application immediately (according to RFC 3261). This method
* enables an implementation to propagate the asynchronous handling of IO
* Exceptions to the application.
*
* @param exceptionEvent the Exception event that is reported to the
* application
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
boolean processIOException(IOExceptionEvent exceptionEvent);
/**
* Processes a Request received on a
* <code>ProtocolProviderServiceSipImpl</code> upon which this processor is
* registered.
*
* @param requestEvent requestEvent fired from the
* <code>ProtocolProviderServiceSipImpl</code> to the processor
* representing a Request received from the network
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
boolean processRequest(RequestEvent requestEvent);
/**
* Processes a Response received on a
* <code>ProtocolProviderServiceSipImpl</code> upon which this processor is
* registered.
*
* @param responseEvent the responseEvent fired from the
* <code>ProtocolProviderServiceSipImpl</code> to the processor
* representing a Response received from the network
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
boolean processResponse(ResponseEvent responseEvent);
/**
* Processes a retransmit or expiration Timeout of an underlying
* {@link Transaction} handled by this SipListener. This Event notifies the
* application that a retransmission or transaction Timer expired in the
* SipProvider's transaction state machine. The TimeoutEvent encapsulates
* the specific timeout type and the transaction identifier either client or
* server upon which the timeout occurred. The type of Timeout can by
* determined by:
* <code>timeoutType = timeoutEvent.getTimeout().getValue();</code>
*
* @param timeoutEvent the timeoutEvent received indicating either the
* message retransmit or transaction timed out
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
boolean processTimeout(TimeoutEvent timeoutEvent);
/**
* Process an asynchronously reported TransactionTerminatedEvent. When a
* transaction transitions to the Terminated state, the stack keeps no
* further records of the transaction. This notification can be used by
* applications to clean up any auxiliary data that is being maintained for
* the given transaction.
*
* @param transactionTerminatedEvent an event that indicates that the
* transaction has transitioned into the terminated state
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
boolean processTransactionTerminated(
TransactionTerminatedEvent transactionTerminatedEvent);
}

@ -95,7 +95,7 @@ public class OperationSetBasicInstantMessagingSipImpl
offlineMessageSupported = true;
sipProvider.registerMethodProcessor(Request.MESSAGE,
new SipMessageListener());
new BasicInstantMessagingMethodProcessor());
this.sipStatusEnum = sipProvider.getSipStatusEnum();
}
@ -686,31 +686,34 @@ else if (evt instanceof MessageDeliveryFailedEvent)
/**
* Class for listening incoming packets.
*/
private class SipMessageListener
implements SipListener
private class BasicInstantMessagingMethodProcessor
implements MethodProcessor
{
public void processDialogTerminated(
public boolean processDialogTerminated(
DialogTerminatedEvent dialogTerminatedEvent)
{
// never fired
return false;
}
public void processIOException(IOExceptionEvent exceptionEvent)
public boolean processIOException(IOExceptionEvent exceptionEvent)
{
// never fired
return false;
}
public void processTransactionTerminated(
public boolean processTransactionTerminated(
TransactionTerminatedEvent transactionTerminatedEvent)
{
// nothing to do
return false;
}
/**
*
* @param timeoutEvent TimeoutEvent
*/
public void processTimeout(TimeoutEvent timeoutEvent)
public boolean processTimeout(TimeoutEvent timeoutEvent)
{
synchronized (messageProcessors)
{
@ -721,7 +724,7 @@ public void processTimeout(TimeoutEvent timeoutEvent)
= (SipMessageProcessor)iter.next();
if(!listener.processTimeout(timeoutEvent, sentMsg))
return;
return true;
}
}
@ -730,7 +733,7 @@ public void processTimeout(TimeoutEvent timeoutEvent)
if (timeoutEvent.isServerTransaction()) {
logger.warn("The sender has probably not received our OK");
return;
return false;
}
Request req = timeoutEvent.getClientTransaction().getRequest();
@ -753,7 +756,7 @@ public void processTimeout(TimeoutEvent timeoutEvent)
if (toHeader == null)
{
logger.error("received a request without a to header");
return;
return false;
}
Contact to = opSetPersPresence.resolveContactID(
@ -797,15 +800,20 @@ public void processTimeout(TimeoutEvent timeoutEvent)
MessageDeliveryFailedEvent.INTERNAL_ERROR,
new Date());
fireMessageEvent(evt);
return true;
}
/**
* Process a request from a distant contact
*
*
* @param requestEvent the <tt>RequestEvent</tt> containing the newly
* received request.
* received request.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors
* registered for the same method; <tt>false</tt>, otherwise
*/
public void processRequest(RequestEvent requestEvent)
public boolean processRequest(RequestEvent requestEvent)
{
synchronized (messageProcessors)
{
@ -816,7 +824,7 @@ public void processRequest(RequestEvent requestEvent)
= (SipMessageProcessor)iter.next();
if(!listener.processMessage(requestEvent))
return;
return true;
}
}
@ -841,7 +849,7 @@ public void processRequest(RequestEvent requestEvent)
if (fromHeader == null)
{
logger.error("received a request without a from header");
return;
return false;
}
Contact from = opSetPersPresence.resolveContactID(
@ -910,15 +918,20 @@ public void processRequest(RequestEvent requestEvent)
= new MessageReceivedEvent(
newMessage, from, new Date());
fireMessageEvent(msgReceivedEvt);
return true;
}
/**
* Process a response from a distant contact.
*
*
* @param responseEvent the <tt>ResponseEvent</tt> containing the newly
* received SIP response.
* received SIP response.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors
* registered for the same method; <tt>false</tt>, otherwise
*/
public void processResponse(ResponseEvent responseEvent)
public boolean processResponse(ResponseEvent responseEvent)
{
synchronized (messageProcessors)
{
@ -929,7 +942,7 @@ public void processResponse(ResponseEvent responseEvent)
= (SipMessageProcessor)iter.next();
if(!listener.processResponse(responseEvent, sentMsg))
return;
return true;
}
}
@ -956,7 +969,7 @@ public void processResponse(ResponseEvent responseEvent)
{
// should never happen
logger.error("send a request without a to header");
return;
return false;
}
Contact to = opSetPersPresence.resolveContactID(toHeader.getAddress()
@ -981,7 +994,7 @@ public void processResponse(ResponseEvent responseEvent)
new Date());
fireMessageEvent(evt);
return;
return false;
}
// we retrieve the original message
@ -1005,7 +1018,7 @@ public void processResponse(ResponseEvent responseEvent)
new Date());
fireMessageEvent(evt);
return;
return true;
}
// status 401/407 = proxy authentification
@ -1083,6 +1096,8 @@ else if (status >= 200)
// we don't need this message anymore
sentMsg.remove(key);
}
return true;
}
/**

@ -28,8 +28,8 @@
*/
public class OperationSetBasicTelephonySipImpl
extends AbstractOperationSetBasicTelephony
implements OperationSetAdvancedTelephony,
SipListener
implements MethodProcessor,
OperationSetAdvancedTelephony
{
private static final Logger logger =
Logger.getLogger(OperationSetBasicTelephonySipImpl.class);
@ -475,8 +475,11 @@ private void throwOperationFailedException(String message, int errorCode,
* @param requestEvent requestEvent fired from the SipProvider to the
* <tt>SipListener</tt> representing a Request received from the
* network.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processRequest(RequestEvent requestEvent)
public boolean processRequest(RequestEvent requestEvent)
{
ServerTransaction serverTransaction =
requestEvent.getServerTransaction();
@ -497,7 +500,7 @@ public void processRequest(RequestEvent requestEvent)
logger.error("Failed to create a new server"
+ "transaction for an incoming request\n"
+ "(Next message contains the request)", ex);
return;
return false;
}
catch (TransactionUnavailableException ex)
{
@ -505,10 +508,12 @@ public void processRequest(RequestEvent requestEvent)
logger.error("Failed to create a new server"
+ "transaction for an incoming request\n"
+ "(Next message contains the request)", ex);
return;
return false;
}
}
boolean processed = false;
// INVITE
if (requestMethod.equals(Request.INVITE))
{
@ -521,6 +526,7 @@ public void processRequest(RequestEvent requestEvent)
logger.debug("request is an INVITE. Dialog state="
+ dialogState);
processInvite(jainSipProvider, serverTransaction, request);
processed = true;
}
else
{
@ -532,29 +538,35 @@ public void processRequest(RequestEvent requestEvent)
else if (requestMethod.equals(Request.ACK))
{
processAck(serverTransaction, request);
processed = true;
}
// BYE
else if (requestMethod.equals(Request.BYE))
{
processBye(serverTransaction, request);
processed = true;
}
// CANCEL
else if (requestMethod.equals(Request.CANCEL))
{
processCancel(serverTransaction, request);
processed = true;
}
// REFER
else if (requestMethod.equals(Request.REFER))
{
logger.debug("received REFER");
processRefer(serverTransaction, request, jainSipProvider);
processed = true;
}
// NOTIFY
else if (requestMethod.equals(Request.NOTIFY))
{
logger.debug("received NOTIFY");
processNotify(serverTransaction, request);
processed = processNotify(serverTransaction, request);
}
return processed;
}
/**
@ -562,11 +574,15 @@ else if (requestMethod.equals(Request.NOTIFY))
*
* @param transactionTerminatedEvent -- an event that indicates that the
* transaction has transitioned into the terminated state.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processTransactionTerminated(
public boolean processTransactionTerminated(
TransactionTerminatedEvent transactionTerminatedEvent)
{
// nothing to do here.
return false;
}
/**
@ -575,8 +591,11 @@ public void processTransactionTerminated(
*
* @param responseEvent the responseEvent that we received
* ProtocolProviderService.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processResponse(ResponseEvent responseEvent)
public boolean processResponse(ResponseEvent responseEvent)
{
ClientTransaction clientTransaction =
responseEvent.getClientTransaction();
@ -595,6 +614,7 @@ public void processResponse(ResponseEvent responseEvent)
SipProvider sourceProvider = (SipProvider) responseEvent.getSource();
int responseStatusCode = response.getStatusCode();
boolean processed = false;
switch (responseStatusCode)
{
@ -603,6 +623,7 @@ public void processResponse(ResponseEvent responseEvent)
if (method.equals(Request.INVITE))
{
processInviteOK(clientTransaction, response);
processed = true;
}
else if (method.equals(Request.BYE))
{
@ -613,21 +634,25 @@ else if (method.equals(Request.BYE))
// Ringing
case Response.RINGING:
processRinging(clientTransaction, response);
processed = true;
break;
// Session Progress
case Response.SESSION_PROGRESS:
processSessionProgress(clientTransaction, response);
processed = true;
break;
// Trying
case Response.TRYING:
processTrying(clientTransaction, response);
processed = true;
break;
// Busy here.
case Response.BUSY_HERE:
processBusyHere(clientTransaction, response);
processed = true;
break;
// Accepted
@ -635,6 +660,7 @@ else if (method.equals(Request.BYE))
if (Request.REFER.equals(method))
{
processReferAccepted(clientTransaction, response);
processed = true;
}
break;
@ -643,6 +669,7 @@ else if (method.equals(Request.BYE))
case Response.PROXY_AUTHENTICATION_REQUIRED:
processAuthenticationChallenge(clientTransaction, response,
sourceProvider);
processed = true;
break;
// errors
@ -659,10 +686,13 @@ else if (method.equals(Request.BYE))
if (callParticipant != null)
callParticipant.setState(CallParticipantState.FAILED);
processed = true;
}
// ignore everything else.
break;
}
return processed;
}
/**
@ -1159,14 +1189,17 @@ private void processAuthenticationChallenge(
*
* @param timeoutEvent the timeoutEvent received indicating either the
* message retransmit or transaction timed out.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processTimeout(TimeoutEvent timeoutEvent)
public boolean processTimeout(TimeoutEvent timeoutEvent)
{
Transaction transaction;
if (timeoutEvent.isServerTransaction())
{
// don't care. or maybe a stack bug?
return;
return false;
}
else
{
@ -1179,13 +1212,14 @@ public void processTimeout(TimeoutEvent timeoutEvent)
if (callParticipant == null)
{
logger.debug("Got a headless timeout event." + timeoutEvent);
return;
return false;
}
// change status
callParticipant.setState(CallParticipantState.FAILED,
"The remote party has not replied!"
+ "The call will be disconnected");
return true;
}
/**
@ -1198,11 +1232,15 @@ public void processTimeout(TimeoutEvent timeoutEvent)
*
* @param exceptionEvent The Exception event that is reported to the
* application.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processIOException(IOExceptionEvent exceptionEvent)
public boolean processIOException(IOExceptionEvent exceptionEvent)
{
logger.error("Got an asynchronous exception event. host="
+ exceptionEvent.getHost() + " port=" + exceptionEvent.getPort());
return true;
}
/**
@ -1210,8 +1248,11 @@ public void processIOException(IOExceptionEvent exceptionEvent)
*
* @param dialogTerminatedEvent -- an event that indicates that the dialog
* has transitioned into the terminated state.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processDialogTerminated(
public boolean processDialogTerminated(
DialogTerminatedEvent dialogTerminatedEvent)
{
CallParticipantSipImpl callParticipant =
@ -1220,11 +1261,12 @@ public void processDialogTerminated(
if (callParticipant == null)
{
return;
return false;
}
// change status
callParticipant.setState(CallParticipantState.DISCONNECTED);
return true;
}
/**
@ -2005,7 +2047,7 @@ && referToCallStateChanged(referToCallListenerSource,
* @param notifyRequest the <code>Request.NOTIFY</code> request to be
* processed
*/
private void processNotify(ServerTransaction serverTransaction,
private boolean processNotify(ServerTransaction serverTransaction,
Request notifyRequest)
{
@ -2018,7 +2060,7 @@ private void processNotify(ServerTransaction serverTransaction,
if ((eventHeader == null)
|| !"refer".equals(eventHeader.getEventType()))
{
return;
return false;
}
SubscriptionStateHeader ssHeader =
@ -2028,7 +2070,7 @@ private void processNotify(ServerTransaction serverTransaction,
{
logger
.error("NOTIFY of refer event type with no Subscription-State header.");
return;
return false;
}
Dialog dialog = serverTransaction.getDialog();
@ -2037,7 +2079,7 @@ private void processNotify(ServerTransaction serverTransaction,
if (participant == null)
{
logger.debug("Received a stray refer NOTIFY request.");
return;
return false;
}
// OK
@ -2053,7 +2095,7 @@ private void processNotify(ServerTransaction serverTransaction,
logger.error(message, ex);
participant.setState(CallParticipantState.DISCONNECTED, message);
return;
return false;
}
try
{
@ -2066,7 +2108,7 @@ private void processNotify(ServerTransaction serverTransaction,
logger.error(message, ex);
participant.setState(CallParticipantState.DISCONNECTED, message);
return;
return false;
}
if (SubscriptionStateHeader.TERMINATED.equals(ssHeader.getState())
@ -2096,6 +2138,8 @@ private void processNotify(ServerTransaction serverTransaction,
participant.setState(CallParticipantState.DISCONNECTED);
}
}
return true;
}
/**

@ -21,15 +21,15 @@
* tested.
*
* It should actually only be considered as a draft, since it was not heavily
* tested, and just developped enough to get the DTMF function work I copied
* tested, and just developed enough to get the DTMF function work I copied
* and adapted code of the OpSetBasicTelephony implementation for SIP to make
* this code.
*
* @author JM HEITZ
*/
public class OperationSetDTMFSipImpl
implements SipListener,
OperationSetDTMF
implements MethodProcessor,
OperationSetDTMF
{
/**
* logger for the class
@ -143,35 +143,42 @@ private void sayInfo(CallParticipantSipImpl callParticipant,
/**
* Does nothing
*
*
* @param requestEvent the event request
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processRequest(RequestEvent requestEvent)
public boolean processRequest(RequestEvent requestEvent)
{
if (requestEvent == null)
{
logger.debug("requestEvent null");
}
logger.error("We don't cope with requests" + requestEvent);
return false;
}
/**
* Just look if the DTMF signal was well received, and log it
*
*
* @param responseEvent the response event
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processResponse(ResponseEvent responseEvent)
public boolean processResponse(ResponseEvent responseEvent)
{
if (responseEvent == null)
{
logger.debug("null responseEvent");
return;
return false;
}
Response response = responseEvent.getResponse();
if (response == null)
{
logger.debug("null response");
return;
return false;
}
int code = response.getStatusCode();
logger.debug("DTMF status code=" + code);
@ -183,59 +190,74 @@ public void processResponse(ResponseEvent responseEvent)
{
logger.debug("DTMF succeeded");
}
return true;
}
/**
* In case of timeout, just terminate the transaction
*
*
* @param timeoutEvent the timeout event
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processTimeout(TimeoutEvent timeoutEvent)
public boolean processTimeout(TimeoutEvent timeoutEvent)
{
//we do nothing
logger.error("ioexception :" + timeoutEvent);
return false;
}
/**
* Just log the exception
*
*
* @param exceptionEvent the event we have to handle
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processIOException(IOExceptionEvent exceptionEvent)
public boolean processIOException(IOExceptionEvent exceptionEvent)
{
//we do nothing
if (exceptionEvent == null)
{
logger.debug("ioexception null");
return;
return false;
}
logger.error("ioexception :" + exceptionEvent);
return false;
}
/**
* Just log the end of the transaction
*
*
* @param transactionTerminatedEvent the event we have to handle
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processTransactionTerminated(
public boolean processTransactionTerminated(
TransactionTerminatedEvent transactionTerminatedEvent)
{
//we do nothing
logger.info("Transaction Terminated :" + transactionTerminatedEvent);
return false;
}
/**
* Just log the end of the dialog
*
*
* @param dialogTerminatedEvent the event we have to handle
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processDialogTerminated(
public boolean processDialogTerminated(
DialogTerminatedEvent dialogTerminatedEvent)
{
//we do nothing
logger.info("Dialog Terminated :" + dialogTerminatedEvent);
return false;
}
/**

@ -39,7 +39,7 @@
*/
public class OperationSetPresenceSipImpl
extends AbstractOperationSetPersistentPresence<ProtocolProviderServiceSipImpl>
implements SipListener
implements MethodProcessor
{
private static final Logger logger =
Logger.getLogger(OperationSetPresenceSipImpl.class);
@ -1673,14 +1673,17 @@ public void unsubscribe(Contact contact)
/**
* Analyzes the incoming <tt>responseEvent</tt> and then forwards it to the
* proper event handler.
*
*
* @param responseEvent the responseEvent that we received
* ProtocolProviderService.
* ProtocolProviderService.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processResponse(ResponseEvent responseEvent)
public boolean processResponse(ResponseEvent responseEvent)
{
if (this.presenceEnabled == false) {
return;
return false;
}
ClientTransaction clientTransaction = responseEvent
@ -1691,11 +1694,12 @@ public void processResponse(ResponseEvent responseEvent)
if (cseq == null)
{
logger.error("An incoming response did not contain a CSeq header");
return;
return false;
}
String method = cseq.getMethod();
SipProvider sourceProvider = (SipProvider)responseEvent.getSource();
boolean processed = false;
// SUBSCRIBE
if (method.equals(Request.SUBSCRIBE)) {
@ -1721,6 +1725,7 @@ public void processResponse(ResponseEvent responseEvent)
try {
processAuthenticationChallenge(clientTransaction,
response, sourceProvider);
processed = true;
} catch (OperationFailedException e) {
logger.error("can't handle the challenge", e);
}
@ -1731,11 +1736,12 @@ public void processResponse(ResponseEvent responseEvent)
synchronized (this.waitedCallIds) {
this.waitedCallIds.remove(idheader.getCallId());
}
processed = true;
}
// any other cases (200/202) will imply a NOTIFY, so we will
// handle the end of a subscription there
return;
return processed;
}
@ -1749,7 +1755,7 @@ public void processResponse(ResponseEvent responseEvent)
if (expHeader == null) {
// not conform to rfc3265
logger.error("no Expires header in this response");
return;
return false;
}
if (contact.getResfreshTask() != null) {
@ -1798,7 +1804,7 @@ public void processResponse(ResponseEvent responseEvent)
logger.debug("failed to finalize the subscription of the" +
"contact", e);
return;
return false;
}
}
}
@ -1819,7 +1825,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
if (min == null) {
logger.error("no minimal expires value in this 423 " +
"response");
return;
return false;
}
Request request = responseEvent.getClientTransaction()
@ -1831,7 +1837,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
exp.setExpires(min.getExpires());
} catch (InvalidArgumentException e) {
logger.error("can't set the new expires value", e);
return;
return false;
}
ClientTransaction transac = null;
@ -1840,17 +1846,17 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
.getNewClientTransaction(request);
} catch (TransactionUnavailableException e) {
logger.error("can't create the client transaction", e);
return;
return false;
}
try {
transac.sendRequest();
} catch (SipException e) {
logger.error("can't send the new request", e);
return;
return false;
}
return;
return true;
// UNAUTHORIZED (401/407)
} else if (response.getStatusCode() == Response.UNAUTHORIZED
|| response.getStatusCode() == Response
@ -1912,8 +1918,30 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
response.getReasonPhrase());
}
}
processed = true;
// NOTIFY
} else if (method.equals(Request.NOTIFY)) {
}
else if (method.equals(Request.NOTIFY))
{
/*
* Make sure we're working only on responses to NOTIFY requests
* we're interested in.
*/
Request notifyRequest = clientTransaction.getRequest();
if (notifyRequest != null)
{
EventHeader eventHeader =
(EventHeader) notifyRequest.getHeader(EventHeader.NAME);
if ((eventHeader == null)
|| !"presence".equalsIgnoreCase(eventHeader.getEventType()))
{
return false;
}
}
// if it's a final response to a NOTIFY, we try to remove it from
// the list of waited NOTIFY end
if (response.getStatusCode() != Response.UNAUTHORIZED
@ -1988,6 +2016,8 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
}
}
processed = true;
// PUBLISH
} else if (method.equals(Request.PUBLISH)) {
// if it's a final response to a PUBLISH, we try to remove it from
@ -2012,7 +2042,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
// must be one (rfc3903)
if (etHeader == null) {
logger.debug("can't find the ETag header");
return;
return false;
}
this.distantPAET = etHeader.getETag();
@ -2023,7 +2053,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
if (expires == null) {
logger.error("no Expires header in the response");
return;
return false;
}
// if it's a response to an unpublish request (Expires: 0),
@ -2031,7 +2061,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
if (expires.getExpires() == 0)
{
this.distantPAET = null;
return;
return true;
}
// just to be sure to not have two refreshing task
@ -2057,7 +2087,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
response, sourceProvider);
} catch (OperationFailedException e) {
logger.error("can't handle the challenge", e);
return;
return false;
}
// INTERVAL TOO BRIEF (423)
} else if (response.getStatusCode() == Response.INTERVAL_TOO_BRIEF)
@ -2069,7 +2099,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
if (min == null) {
logger.error("can't find a min expires header in the 423" +
" error message");
return;
return false;
}
// send a new publish with the new expires value
@ -2078,7 +2108,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
req = createPublish(min.getExpires(), true);
} catch (OperationFailedException e) {
logger.error("can't create the new publish request", e);
return;
return false;
}
ClientTransaction transac = null;
@ -2088,14 +2118,14 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
.getNewClientTransaction(req);
} catch (TransactionUnavailableException e) {
logger.error("can't create the client transaction", e);
return;
return false;
}
try {
transac.sendRequest();
} catch (SipException e) {
logger.error("can't send the PUBLISH request", e);
return;
return false;
}
// CONDITIONAL REQUEST FAILED (412)
@ -2110,7 +2140,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
req = createPublish(this.subscriptionDuration, true);
} catch (OperationFailedException e) {
logger.error("can't create the new publish request", e);
return;
return false;
}
ClientTransaction transac = null;
@ -2120,14 +2150,14 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
.getNewClientTransaction(req);
} catch (TransactionUnavailableException e) {
logger.error("can't create the client transaction", e);
return;
return false;
}
try {
transac.sendRequest();
} catch (SipException e) {
logger.error("can't send the PUBLISH request", e);
return;
return false;
}
// with every other error, we consider that we have to start a new
@ -2138,7 +2168,7 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
this.distantPAET = null;
if (this.useDistantPA == false) {
return;
return true;
}
logger.debug("we enter into the peer to peer mode as the "
@ -2154,7 +2184,11 @@ else if(response.getStatusCode() >= Response.BAD_REQUEST)
// republish our presence state
}
processed = true;
}
return processed;
}
/**
@ -2404,14 +2438,17 @@ private ClientTransaction createNotify(ContactSipImpl contact, byte[] doc,
/**
* Process a request from a distant contact
*
*
* @param requestEvent the <tt>RequestEvent</tt> containing the newly
* received request.
* received request.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processRequest(RequestEvent requestEvent)
public boolean processRequest(RequestEvent requestEvent)
{
if (this.presenceEnabled == false) {
return;
return false;
}
ServerTransaction serverTransaction = requestEvent
@ -2433,7 +2470,7 @@ public void processRequest(RequestEvent requestEvent)
+ "transaction for an incoming request\n"
+ "(Next message contains the request)"
, ex);
return;
return false;
}
catch (TransactionUnavailableException ex)
{
@ -2442,7 +2479,7 @@ public void processRequest(RequestEvent requestEvent)
+ "transaction for an incoming request\n"
+ "(Next message contains the request)"
, ex);
return;
return false;
}
}
@ -2456,9 +2493,10 @@ public void processRequest(RequestEvent requestEvent)
// listener is ?
// don't send a 489 / Bad event answer here
return;
return false;
}
boolean processed = false;
// NOTIFY
if (request.getMethod().equals(Request.NOTIFY)) {
@ -2472,7 +2510,7 @@ public void processRequest(RequestEvent requestEvent)
// notify must contain one (rfc3265)
if (sstateHeader == null) {
logger.error("no subscription state in this request");
return;
return false;
}
// first handle the case of a contact still pending
@ -2514,7 +2552,7 @@ public void processRequest(RequestEvent requestEvent)
request);
} catch (ParseException e) {
logger.error("failed to create the 481 response", e);
return;
return false;
}
try {
@ -2527,7 +2565,7 @@ public void processRequest(RequestEvent requestEvent)
" to send the response", e);
}
return;
return true;
}
// if we don't understand the content
@ -2544,7 +2582,7 @@ public void processRequest(RequestEvent requestEvent)
request);
} catch (ParseException e) {
logger.error("failed to create the OK response", e);
return;
return false;
}
// we want PIDF
@ -2556,7 +2594,7 @@ public void processRequest(RequestEvent requestEvent)
} catch (ParseException e) {
// should not happen
logger.error("failed to create the accept header", e);
return;
return false;
}
response.setHeader(acceptHeader);
@ -2604,7 +2642,7 @@ public void processRequest(RequestEvent requestEvent)
.createResponse(Response.OK, request);
} catch (ParseException e) {
logger.error("failed to create the OK response", e);
return;
return false;
}
try {
@ -2625,6 +2663,8 @@ public void processRequest(RequestEvent requestEvent)
setPidfPresenceStatus(new String(request.getRawContent()));
}
processed = true;
// SUBSCRIBE
} else if (request.getMethod().equals(Request.SUBSCRIBE)) {
FromHeader from = (FromHeader) request.getHeader(FromHeader.NAME);
@ -2679,7 +2719,7 @@ public void processRequest(RequestEvent requestEvent)
.createResponse(Response.INTERVAL_TOO_BRIEF, request);
} catch (Exception e) {
logger.error("Error while creating the response 423", e);
return;
return false;
}
MinExpiresHeader min = null;
@ -2689,7 +2729,7 @@ public void processRequest(RequestEvent requestEvent)
} catch (InvalidArgumentException e) {
// should not happen
logger.error("can't create the min expires header", e);
return;
return false;
}
response.setHeader(min);
@ -2697,10 +2737,10 @@ public void processRequest(RequestEvent requestEvent)
serverTransaction.sendResponse(response);
} catch (Exception e) {
logger.error("Error while sending the response 423", e);
return;
return false;
}
return;
return true;
}
// is it a subscription refresh ? (no need for synchronize the
@ -2723,7 +2763,7 @@ public void processRequest(RequestEvent requestEvent)
.createResponse(Response.OK, request);
} catch (Exception e) {
logger.error("Error while creating the response 200", e);
return;
return false;
}
// add the expire header
@ -2732,7 +2772,7 @@ public void processRequest(RequestEvent requestEvent)
.createExpiresHeader(expires);
} catch (InvalidArgumentException e) {
logger.error("Can't create the expires header");
return;
return false;
}
response.setHeader(expHeader);
@ -2740,10 +2780,10 @@ public void processRequest(RequestEvent requestEvent)
serverTransaction.sendResponse(response);
} catch (Exception e) {
logger.error("Error while sending the response 200", e);
return;
return false;
}
return;
return true;
}
Dialog dialog = contact.getServerDialog();
@ -2767,7 +2807,7 @@ public void processRequest(RequestEvent requestEvent)
.createResponse(Response.OK, request);
} catch (Exception e) {
logger.error("Error while creating the response 200", e);
return;
return false;
}
// add the expire header
@ -2776,7 +2816,7 @@ public void processRequest(RequestEvent requestEvent)
.createExpiresHeader(0);
} catch (InvalidArgumentException e) {
logger.error("Can't create the expires header", e);
return;
return false;
}
response.setHeader(expHeader);
@ -2784,7 +2824,7 @@ public void processRequest(RequestEvent requestEvent)
serverTransaction.sendResponse(response);
} catch (Exception e) {
logger.error("Error while sending the response 200", e);
return;
return false;
}
// then terminate the subscription with an ultimate NOTIFY
@ -2797,17 +2837,17 @@ public void processRequest(RequestEvent requestEvent)
SubscriptionStateHeader.TIMEOUT);
} catch (OperationFailedException e) {
logger.error("failed to create the new notify", e);
return;
return false;
}
try {
dialog.sendRequest(transac);
} catch (Exception e) {
logger.error("Can't send the request", e);
return;
return false;
}
return;
return true;
}
// if the contact was already subscribed, we close the last
@ -2829,7 +2869,7 @@ public void processRequest(RequestEvent requestEvent)
SubscriptionStateHeader.REJECTED);
} catch (OperationFailedException e) {
logger.error("failed to create the new notify", e);
return;
return false;
}
contact.setServerDialog(null);
@ -2847,7 +2887,7 @@ public void processRequest(RequestEvent requestEvent)
dialog.sendRequest(transac);
} catch (Exception e) {
logger.error("Can't send the request", e);
return;
return false;
}
}
@ -2866,7 +2906,7 @@ public void processRequest(RequestEvent requestEvent)
.createResponse(Response.OK, request);
} catch (Exception e) {
logger.error("Error while creating the response 200", e);
return;
return false;
}
// add the expire header
@ -2875,7 +2915,7 @@ public void processRequest(RequestEvent requestEvent)
.createExpiresHeader(expires);
} catch (InvalidArgumentException e) {
logger.error("Can't create the expires header", e);
return;
return false;
}
response.setHeader(expHeader);
@ -2883,7 +2923,7 @@ public void processRequest(RequestEvent requestEvent)
serverTransaction.sendResponse(response);
} catch (Exception e) {
logger.error("Error while sending the response 200", e);
return;
return false;
}
// send a NOTIFY
@ -2896,14 +2936,14 @@ public void processRequest(RequestEvent requestEvent)
null);
} catch (OperationFailedException e) {
logger.error("failed to create the new notify", e);
return;
return false;
}
try {
dialog.sendRequest(transac);
} catch (Exception e) {
logger.error("Can't send the request", e);
return;
return false;
}
// add him to our watcher list
@ -2916,6 +2956,8 @@ public void processRequest(RequestEvent requestEvent)
contact.setTimeoutTask(timeout);
getTimer().schedule(timeout, expires * 1000);
processed = true;
// PUBLISH
} else if (request.getMethod().equals(Request.PUBLISH)) {
// we aren't supposed to receive a publish so just say "not
@ -2928,59 +2970,79 @@ public void processRequest(RequestEvent requestEvent)
.createResponse(Response.NOT_IMPLEMENTED, request);
} catch (Exception e) {
logger.error("Error while creating the response 501", e);
return;
return false;
}
try {
serverTransaction.sendResponse(response);
} catch (Exception e) {
logger.error("Error while sending the response 501", e);
return;
return false;
}
processed = true;
}
return processed;
}
/**
* Called when a dialog is terminated
*
*
* @param dialogTerminatedEvent DialogTerminatedEvent
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processDialogTerminated(
public boolean processDialogTerminated(
DialogTerminatedEvent dialogTerminatedEvent)
{
// never fired
return false;
}
/**
* Called when an IO error occurs
*
*
* @param exceptionEvent IOExceptionEvent
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processIOException(IOExceptionEvent exceptionEvent)
public boolean processIOException(IOExceptionEvent exceptionEvent)
{
// never fired
return false;
}
/**
* Called when a transaction is terminated
*
*
* @param transactionTerminatedEvent TransactionTerminatedEvent
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processTransactionTerminated(
public boolean processTransactionTerminated(
TransactionTerminatedEvent transactionTerminatedEvent)
{
// nothing to do
return false;
}
/**
* Called when a timeout occur
*
*
* @param timeoutEvent TimeoutEvent
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processTimeout(TimeoutEvent timeoutEvent)
public boolean processTimeout(TimeoutEvent timeoutEvent)
{
logger.error("timeout reached, it looks really abnormal: " +
timeoutEvent.toString());
return false;
}
/**

@ -29,6 +29,7 @@
* A SIP implementation of the Protocol Provider Service.
*
* @author Emil Ivov
* @author Lubomir Marinov
*/
public class ProtocolProviderServiceSipImpl
extends AbstractProtocolProviderService
@ -128,7 +129,8 @@ public class ProtocolProviderServiceSipImpl
* implement the SipListener interface). Whenever a new message arrives we
* extract its method and hand it to the processor instance registered
*/
private Hashtable methodProcessors = new Hashtable();
private final Hashtable<String, List<MethodProcessor>> methodProcessors =
new Hashtable<String, List<MethodProcessor>>();
/**
* The name of the property under which the jain-sip-ri would expect to find
@ -1064,17 +1066,22 @@ public void processResponse(ResponseEvent responseEvent)
//find the object that is supposed to take care of responses with the
//corresponding method
SipListener processor = (SipListener)methodProcessors.get(method);
List<MethodProcessor> processors = methodProcessors.get(method);
if(processor == null)
if (processors != null)
{
return;
}
logger.debug("Found one processor for method " + method
+ ", processor is=" + processor.toString());
logger.debug("Found " + processors.size()
+ " processor(s) for method " + method);
processor.processResponse(responseEvent);
for (Iterator<MethodProcessor> processorIter =
processors.iterator(); processorIter.hasNext();)
{
if (processorIter.next().processResponse(responseEvent))
{
break;
}
}
}
}
/**
@ -1083,7 +1090,7 @@ public void processResponse(ResponseEvent responseEvent)
* application that a retransmission or transaction Timer expired in the
* SipProvider's transaction state machine. The TimeoutEvent encapsulates
* the specific timeout type and the transaction identifier either client or
* server upon which the timeout occured. The type of Timeout can by
* server upon which the timeout occurred. The type of Timeout can by
* determined by:
* <code>timeoutType = timeoutEvent.getTimeout().getValue();</code>
*
@ -1110,18 +1117,23 @@ public void processTimeout(TimeoutEvent timeoutEvent)
//find the object that is supposed to take care of responses with the
//corresponding method
SipListener processor
= (SipListener)methodProcessors.get(request.getMethod());
String method = request.getMethod();
List<MethodProcessor> processors = methodProcessors.get(method);
if (processor == null)
if (processors != null)
{
return;
}
logger.debug("Found " + processors.size()
+ " processor(s) for method " + method);
logger.debug("Found one processor for method " + request.getMethod()
+ ", processor is=" + processor.toString());
processor.processTimeout(timeoutEvent);
for (Iterator<MethodProcessor> processorIter =
processors.iterator(); processorIter.hasNext();)
{
if (processorIter.next().processTimeout(timeoutEvent))
{
break;
}
}
}
}
/**
@ -1156,18 +1168,24 @@ public void processTransactionTerminated(TransactionTerminatedEvent
//find the object that is supposed to take care of responses with the
//corresponding method
SipListener processor
= (SipListener)methodProcessors.get(request.getMethod());
String method = request.getMethod();
List<MethodProcessor> processors = methodProcessors.get(method);
if(processor == null)
if (processors != null)
{
return;
}
logger.debug("Found one processor for method " + request.getMethod()
+ ", processor is=" + processor.toString());
logger.debug("Found " + processors.size()
+ " processor(s) for method " + method);
processor.processTransactionTerminated(transactionTerminatedEvent);
for (Iterator<MethodProcessor> processorIter =
processors.iterator(); processorIter.hasNext();)
{
if (processorIter.next().processTransactionTerminated(
transactionTerminatedEvent))
{
break;
}
}
}
}
/**
@ -1273,17 +1291,22 @@ public void processRequest(RequestEvent requestEvent)
//find the object that is supposed to take care of responses with the
//corresponding method
SipListener processor = (SipListener)methodProcessors.get(method);
List<MethodProcessor> processors = methodProcessors.get(method);
if(processor == null)
if (processors != null)
{
return;
}
logger.debug("Found one processor for method " + method
+ ", processor is=" + processor.toString());
logger.debug("Found " + processors.size()
+ " processor(s) for method " + method);
processor.processRequest(requestEvent);
for (Iterator<MethodProcessor> processorIter =
processors.iterator(); processorIter.hasNext();)
{
if (processorIter.next().processRequest(requestEvent))
{
break;
}
}
}
}
/**
@ -2080,33 +2103,50 @@ else if(proxyTransport.equalsIgnoreCase(ListeningPoint.TLS))
}
/**
* Registers <tt>methodProcessor</tt> in the <tt>methorProcessors</tt>
* table so that it would receives all messages in a transaction initiated
* by a <tt>method</tt> request. If any previous processors exist for the
* same method, they will be replaced by this one.
*
* Registers <tt>methodProcessor</tt> in the <tt>methorProcessors</tt> table
* so that it would receives all messages in a transaction initiated by a
* <tt>method</tt> request. If any previous processors exist for the same
* method, they will be replaced by this one.
*
* @param method a String representing the SIP method that we're registering
* the processor for (e.g. INVITE, REGISTER, or SUBSCRIBE).
* @param methodProcessor a <tt>SipListener</tt> implementation that would
* handle all messages received within a <tt>method</tt> transaction.
* the processor for (e.g. INVITE, REGISTER, or SUBSCRIBE).
* @param methodProcessor a <tt>MethodProcessor</tt> implementation that
* would handle all messages received within a <tt>method</tt>
* transaction.
*/
public void registerMethodProcessor(String method,
SipListener methodProcessor)
public void registerMethodProcessor(String method,
MethodProcessor methodProcessor)
{
this.methodProcessors.put(method, methodProcessor);
List<MethodProcessor> processors = methodProcessors.get(method);
if (processors == null)
{
processors = new LinkedList<MethodProcessor>();
methodProcessors.put(method, processors);
}
if (processors.contains(methodProcessor) == false)
{
processors.add(methodProcessor);
}
}
/**
* Unregisters <tt>methodProcessor</tt> from the <tt>methorProcessors</tt>
* table so that it won't receive further messages in a transaction
* initiated by a <tt>method</tt> request.
*
*
* @param method the name of the method whose processor we'd like to
* unregister.
* unregister.
* @param methodProcessor
*/
public void unregisterMethodProcessor(String method)
public void unregisterMethodProcessor(String method,
MethodProcessor methodProcessor)
{
this.methodProcessors.remove(method);
List<MethodProcessor> processors = methodProcessors.get(method);
if ((processors != null) && processors.remove(methodProcessor)
&& (processors.size() <= 0))
{
methodProcessors.remove(method);
}
}
/**

@ -25,7 +25,7 @@
* @author Emil Ivov
*/
public class SipRegistrarConnection
implements SipListener
implements MethodProcessor
{
private static final Logger logger =
Logger.getLogger(SipRegistrarConnection.class);
@ -879,13 +879,16 @@ private SipProvider getRegistrarJainSipProvider()
}
/**
* Analyses the incoming <tt>responseEvent</tt> and then forwards it to the
* Analyzes the incoming <tt>responseEvent</tt> and then forwards it to the
* proper event handler.
*
*
* @param responseEvent the responseEvent that we received
* ProtocolProviderService.
* ProtocolProviderService.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processResponse(ResponseEvent responseEvent)
public boolean processResponse(ResponseEvent responseEvent)
{
ClientTransaction clientTransaction = responseEvent
.getClientTransaction();
@ -898,14 +901,17 @@ public void processResponse(ResponseEvent responseEvent)
Response responseClone = (Response) response.clone();
SipProvider sourceProvider = (SipProvider)responseEvent.getSource();
boolean processed = false;
//OK
if (response.getStatusCode() == Response.OK) {
processOK(clientTransaction, response);
processed = true;
}
//NOT_IMPLEMENTED
else if (response.getStatusCode() == Response.NOT_IMPLEMENTED) {
processNotImplemented(clientTransaction, response);
processed = true;
}
//Trying
else if (response.getStatusCode() == Response.TRYING) {
@ -919,6 +925,7 @@ else if (response.getStatusCode() == Response.UNAUTHORIZED
processAuthenticationChallenge(clientTransaction
, response
, sourceProvider);
processed = true;
}
//403 FORBIDDEN
else if (response.getStatusCode() == Response.FORBIDDEN)
@ -926,6 +933,7 @@ else if (response.getStatusCode() == Response.FORBIDDEN)
processForbidden(clientTransaction
, response
, sourceProvider);
processed = true;
}
//errors
else if ( response.getStatusCode() / 100 == 4 )
@ -939,8 +947,11 @@ else if ( response.getStatusCode() / 100 == 4 )
, "Received an error while trying to register. "
+ "Server returned error:" + response.getReasonPhrase()
);
processed = true;
}
//ignore everything else.
return processed;
}
/**
@ -1045,73 +1056,91 @@ private void processForbidden(
/**
* Process an asynchronously reported DialogTerminatedEvent.
* When a dialog transitions to the Terminated state, the stack
* keeps no further records of the dialog. This notification can be used by
* applications to clean up any auxiliary data that is being maintained
* for the given dialog.
*
* @param dialogTerminatedEvent -- an event that indicates that the
* dialog has transitioned into the terminated state.
* Process an asynchronously reported DialogTerminatedEvent. When a dialog
* transitions to the Terminated state, the stack keeps no further records
* of the dialog. This notification can be used by applications to clean up
* any auxiliary data that is being maintained for the given dialog.
*
* @param dialogTerminatedEvent -- an event that indicates that the dialog
* has transitioned into the terminated state.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
* @since v1.2
*/
public void processDialogTerminated(DialogTerminatedEvent
public boolean processDialogTerminated(DialogTerminatedEvent
dialogTerminatedEvent)
{
return false;
}
/**
* Processes a Request received on a SipProvider upon which this SipListener
* is registered.
* <p>
*
* @param requestEvent requestEvent fired from the SipProvider to the
* SipListener representing a Request received from the network.
* SipListener representing a Request received from the network.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processRequest(RequestEvent requestEvent)
public boolean processRequest(RequestEvent requestEvent)
{
/** @todo send not implemented */
return false;
}
/**
* Processes a retransmit or expiration Timeout of an underlying
* {@link Transaction}handled by this SipListener.
*
*
* @param timeoutEvent the timeoutEvent received indicating either the
* message retransmit or transaction timed out.
* message retransmit or transaction timed out.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processTimeout(TimeoutEvent timeoutEvent)
public boolean processTimeout(TimeoutEvent timeoutEvent)
{
//don't alert the user if we're already off
if(getRegistrationState().equals(RegistrationState.UNREGISTERED))
return;
setRegistrationState(
RegistrationState.CONNECTION_FAILED
, RegistrationStateChangeEvent.REASON_NOT_SPECIFIED
, "A timeout occurred while trying to connect to the server.");
// don't alert the user if we're already off
if (getRegistrationState().equals(RegistrationState.UNREGISTERED) == false)
{
setRegistrationState(RegistrationState.CONNECTION_FAILED,
RegistrationStateChangeEvent.REASON_NOT_SPECIFIED,
"A timeout occurred while trying to connect to the server.");
}
return true;
}
/**
* Process an asynchronously reported TransactionTerminatedEvent.
* When a transaction transitions to the Terminated state, the stack
* keeps no further records of the transaction.
*
* Process an asynchronously reported TransactionTerminatedEvent. When a
* transaction transitions to the Terminated state, the stack keeps no
* further records of the transaction.
*
* @param transactionTerminatedEvent an event that indicates that the
* transaction has transitioned into the terminated state.
* transaction has transitioned into the terminated state.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processTransactionTerminated(TransactionTerminatedEvent
public boolean processTransactionTerminated(TransactionTerminatedEvent
transactionTerminatedEvent)
{
//doesn't mean anything. we do failure handling in processTimeout
return false;
}
/**
* Process an asynchronously reported IO Exception.
*
*
* @param exceptionEvent The Exception event that is reported to the
* application.
* application.
* @return <tt>true</tt> if the specified event has been handled by this
* processor and shouldn't be offered to other processors registered
* for the same method; <tt>false</tt>, otherwise
*/
public void processIOException(IOExceptionEvent exceptionEvent)
public boolean processIOException(IOExceptionEvent exceptionEvent)
{
setRegistrationState(
RegistrationState.CONNECTION_FAILED
@ -1120,6 +1149,7 @@ public void processIOException(IOExceptionEvent exceptionEvent)
+ "[" + exceptionEvent.getHost() + "]:"
+ exceptionEvent.getPort() + "/"
+ exceptionEvent.getTransport());
return true;
}
/**

Loading…
Cancel
Save