diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ClientCapabilities.java b/src/net/java/sip/communicator/impl/protocol/sip/ClientCapabilities.java
index 590b4db96..94ee5f6de 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ClientCapabilities.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ClientCapabilities.java
@@ -63,10 +63,21 @@ public void processRequest(RequestEvent requestEvent)
optionsOK.addHeader(
provider.getHeaderFactory().createAllowHeader(method));
-
- //add a user agent header.
- optionsOK.setHeader( provider.getSipCommUserAgentHeader());
}
+
+ Iterator events = provider.getKnownEventsList().iterator();
+
+ synchronized (provider.getKnownEventsList()) {
+ while (events.hasNext()) {
+ String event = (String) events.next();
+
+ optionsOK.addHeader(provider.getHeaderFactory()
+ .createAllowEventsHeader(event));
+ }
+ }
+
+ //add a user agent header.
+ optionsOK.setHeader(provider.getSipCommUserAgentHeader());
}
catch (ParseException ex)
{
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java
index 33dc0658b..6882f67c5 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java
@@ -39,7 +39,7 @@ public class OperationSetPresenceSipImpl
implements OperationSetPersistentPresence, SipListener
{
private static final Logger logger =
- Logger.getLogger(OperationSetPersistentPresenceSipImpl.class);
+ Logger.getLogger(OperationSetPresenceSipImpl.class);
/**
* A list of listeners registered for SubscriptionEvents.
*/
@@ -101,12 +101,6 @@ public class OperationSetPresenceSipImpl
* Content : String
*/
private Vector waitedCallIds = new Vector();
-
- /**
- * Hashtable of the pending NOTIFY requests (NOTIFY received before a OK)
- * index : String, Content : RequestEvent
- */
- private Hashtable pendingNotify = new Hashtable();
/**
* Do we have to use a distant presence agent (default initial value)
@@ -255,6 +249,8 @@ public OperationSetPresenceSipImpl(ProtocolProviderServiceSipImpl provider,
this.parentProvider.registerMethodProcessor(Request.NOTIFY, this);
this.parentProvider.registerMethodProcessor(Request.PUBLISH, this);
+ this.parentProvider.registerEvent("presence");
+
logger.debug("presence initialized with :" + isPresenceEnabled + ", "
+ forceP2PMode + ", " + pollingPeriod + ", "
+ subscriptionExpiration + " for "
@@ -2703,7 +2699,7 @@ public void processRequest(RequestEvent requestEvent)
getPidfPresenceStatus((ContactSipImpl)
getLocalContact()),
SubscriptionStateHeader.TERMINATED,
- SubscriptionStateHeader.DEACTIVATED);
+ SubscriptionStateHeader.REJECTED);
} catch (OperationFailedException e) {
logger.error("failed to create the new notify", e);
return;
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
index f2d0693bf..bdf390a5f 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
@@ -59,6 +59,11 @@ public class ProtocolProviderServiceSipImpl
* RegistrationStateChangeEvents.
*/
private List registrationListeners = new ArrayList();
+
+ /**
+ * A list of all events registered for this provider.
+ */
+ private List registeredEvents = new ArrayList();
/**
* The SipFactory instance used to create the SipStack and the Address
@@ -381,6 +386,30 @@ public String getProtocolName()
{
return ProtocolNames.SIP;
}
+
+ /**
+ * Register a new event taken in account by this provider. This is usefull
+ * to generate the Allow-Events header of the OPTIONS responses and to
+ * generate 489 responses.
+ *
+ * @param event The event to register
+ */
+ public void registerEvent(String event) {
+ synchronized (this.registeredEvents) {
+ if (!this.registeredEvents.contains(event)) {
+ this.registeredEvents.add(event);
+ }
+ }
+ }
+
+ /**
+ * Returns the list of all the registered events for this provider.
+ *
+ * @return The list of all the registered events
+ */
+ public List getKnownEventsList() {
+ return this.registeredEvents;
+ }
/**
* Indicates whether or not this provider is registered
@@ -1160,6 +1189,74 @@ public void processRequest(RequestEvent requestEvent)
logger.debug("received request=\n" + requestEvent.getRequest());
Request request = requestEvent.getRequest();
+
+ // test if an Event header is present and known
+ EventHeader eventHeader = (EventHeader)
+ request.getHeader(EventHeader.NAME);
+
+ if (eventHeader != null) {
+ boolean eventKnown;
+
+ synchronized (this.registeredEvents) {
+ eventKnown = this.registeredEvents.contains(
+ eventHeader.getEventType());
+ }
+
+ if (!eventKnown) {
+ // send a 489 / Bad Event response
+ ServerTransaction serverTransaction = requestEvent
+ .getServerTransaction();
+ SipProvider jainSipProvider = (SipProvider)
+ requestEvent.getSource();
+
+ if (serverTransaction == null)
+ {
+ try
+ {
+ serverTransaction = jainSipProvider
+ .getNewServerTransaction(request);
+ }
+ catch (TransactionAlreadyExistsException ex)
+ {
+ //let's not scare the user and only log a message
+ logger.error("Failed to create a new server"
+ + "transaction for an incoming request\n"
+ + "(Next message contains the request)"
+ , ex);
+ return;
+ }
+ catch (TransactionUnavailableException ex)
+ {
+ //let's not scare the user and only log a message
+ logger.error("Failed to create a new server"
+ + "transaction for an incoming request\n"
+ + "(Next message contains the request)"
+ , ex);
+ return;
+ }
+ }
+
+ Response response = null;
+ try {
+ response = this.getMessageFactory().createResponse(
+ Response.BAD_EVENT, request);
+ } catch (ParseException e) {
+ logger.error("failed to create the 489 response", e);
+ return;
+ }
+
+ try {
+ serverTransaction.sendResponse(response);
+ } catch (SipException e) {
+ logger.error("failed to send the response", e);
+ } catch (InvalidArgumentException e) {
+ // should not happen
+ logger.error("invalid argument provided while trying" +
+ " to send the response", e);
+ }
+ }
+ }
+
String method = request.getMethod();