Revision: 16151
Author: vladimir.ralev
Date: Mon Jan 3 05:51:04 2011
Log: Update Issue 2251
Fix + test
http://code.google.com/p/mobicents/source/detail?r=16151
Modified:
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/MobicentsSipSession.java
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionImpl.java
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipSessionFacade.java
/trunk/servers/sip-servlets/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServlet.java
/trunk/servers/sip-servlets/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/TestSipListener.java
/trunk/servers/sip-servlets/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistSipServletTest.java
=======================================
---
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java
Mon Dec 6 10:12:43 2010
+++
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java
Mon Jan 3 05:51:04 2011
@@ -143,6 +143,8 @@
}
}
final String branch = viaHeader.getBranch();
+
+ final int status = sipServletResponse.getStatus();
String strippedBranchId =
branch.substring(BRANCH_MAGIC_COOKIE.length());
int indexOfUnderscore = strippedBranchId.indexOf("_");
if(indexOfUnderscore == -1) {
@@ -215,10 +217,16 @@
} else {
// This piece of code move here due to Proxy-B2bua case for
http://code.google.com/p/mobicents/issues/detail?id=1986
if(tmpSession.getProxy() == null &&
sipServletResponse.isRetransmission()) {
- if(logger.isDebugEnabled()) {
- logger.debug("retransmission received for a non proxy application,
dropping the response " + response);
- }
- return ;
+ if(status == 183
&& !response.toString().equals(tmpSession.getLast183Response())) {
+ if(logger.isDebugEnabled()) {
+ logger.debug("early media changed
http://code.google.com/p/mobicents/issues/detail?id=2251 , not a
retransmission " + response);
+ }
+ } else {
+ if(logger.isDebugEnabled()) {
+ logger.debug("retransmission received for a non proxy application,
dropping the response " + response);
+ }
+ return ;
+ }
}
sipServletResponse.setSipSession(tmpSession);
}
@@ -245,7 +253,6 @@
if(originalRequest !=
null) {
originalRequest.setResponse(sipServletResponse);
}
- final int status =
sipServletResponse.getStatus();
// RFC 3265 : If a 200-class response matches such a SUBSCRIBE or
REFER request,
// it creates a new
subscription and a new dialog.
// Issue 1481
http://code.google.com/p/mobicents/issues/detail?id=1481
@@ -325,10 +332,16 @@
// This issue showed that retransmissions of 180 Ringing were
passed
// to the application so we make sure to drop them in case of
UAC/UAS
if(sipServletResponse.isRetransmission()) {
-
if(logger.isDebugEnabled()) {
- logger.debug("the following response is dropped since this is a
retransmission " + response);
- }
- return;
+ if(status == 183
&& !response.toString().equals(session.getLast183Response())) {
+
if(logger.isDebugEnabled()) {
+ logger.debug("the following response is not dropped to recover
early media changes, see
http://code.google.com/p/mobicents/issues/detail?id=2251 :" + response);
+
}
+ } else {
+
if(logger.isDebugEnabled()) {
+ logger.debug("the following response is dropped since this is a
retransmission " + response);
+
}
+
return;
+ }
}
//if this is a
trying response, the response is dropped
if(Response.TRYING == status) {
@@ -354,6 +367,12 @@
callServlet(sipServletResponse);
forwardResponseStatefully(sipServletResponse);
+
+ if(status ==
183) {
+
session.setLast183Response(response.toString());
+ } else if(status
>= 200) {
+ session.setLast183Response(null); // cleanup after the final
response, 183 is no longer needed to find retransmissions
+ }
}
} catch (ServletException e) {
throw new DispatcherException("Unexpected servlet exception while
processing the response : " + response, e);
=======================================
---
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/MobicentsSipSession.java
Mon Dec 20 13:46:40 2010
+++
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/MobicentsSipSession.java
Mon Jan 3 05:51:04 2011
@@ -167,4 +167,8 @@
void setSipSessionSecurity(SipSessionSecurity sipSessionSecurity);
SipSessionSecurity getSipSessionSecurity();
-}
+
+ public String getLast183Response();
+
+ public void setLast183Response(String last183Response);
+}
=======================================
---
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionImpl.java
Tue Dec 28 19:42:35 2010
+++
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionImpl.java
Mon Jan 3 05:51:04 2011
@@ -269,6 +269,9 @@
// Handle Header [Authentication-Info: nextnonce="xyz"] in sip
authorization responses
protected transient SipSessionSecurity sipSessionSecurity;
+ // http://code.google.com/p/mobicents/issues/detail?id=2251
+ protected String last183Response = null;
+
protected SipSessionImpl (SipSessionKey key, SipFactoryImpl
sipFactoryImpl, MobicentsSipApplicationSession
mobicentsSipApplicationSession) {
this.key = key;
setSipApplicationSession(mobicentsSipApplicationSession);
@@ -2155,5 +2158,11 @@
sipSessionSecurity = new SipSessionSecurity();
}
return sipSessionSecurity;
+ }
+ public String getLast183Response() {
+ return last183Response;
+ }
+ public void setLast183Response(String last183Response) {
+ this.last183Response = last183Response;
}
}
=======================================
---
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipSessionFacade.java
Mon Dec 20 13:46:40 2010
+++
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipSessionFacade.java
Mon Jan 3 05:51:04 2011
@@ -478,5 +478,13 @@
public void setSipSessionSecurity(SipSessionSecurity
sipSessionSecurity) {
sipSession.setSipSessionSecurity(sipSessionSecurity);
}
+
+ public void setLast183Response(String last183Response) {
+ sipSession.setLast183Response(last183Response);
+ }
+
+ public String getLast183Response() {
+ return sipSession.getLast183Response();
+ }
}
=======================================
---
/trunk/servers/sip-servlets/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServlet.java
Tue Dec 28 18:56:39 2010
+++
/trunk/servers/sip-servlets/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServlet.java
Mon Jan 3 05:51:04 2011
@@ -55,7 +55,10 @@
private static final String CONTENT_TYPE = "text/plain;charset=UTF-8";
private static final String ENCODE_URI = "encodedURI";
private static final String TEST_ERROR_RESPONSE = "testErrorResponse";
- private static transient Logger logger =
Logger.getLogger(ShootistSipServlet.class);
+ private static transient Logger logger =
Logger.getLogger(ShootistSipServlet.class);
+
+ int numberOf183Responses = 0;
+
@Resource
TimerService timerService;
@Resource
@@ -73,7 +76,8 @@
@Override
protected void doProvisionalResponse(SipServletResponse resp)
- throws ServletException, IOException {
+ throws ServletException, IOException {
+ if(resp.getStatus() == 183) numberOf183Responses++;
if(resp.getHeader("require") != null) {
SipServletRequest prack = resp.createPrack();
SipFactory sipFactory = (SipFactory)
getServletContext().getAttribute(SIP_FACTORY);
@@ -433,6 +437,8 @@
sipServletRequest.setRequestURI(sipUri);
sipServletRequest.setContentLength(content.length());
sipServletRequest.setContent(content, CONTENT_TYPE);
+ sipServletRequest.setHeader("EarlyMediaResponses", new
Integer(numberOf183Responses).toString());
+
sipServletRequest.send();
} catch (ServletParseException e) {
logger.error("Exception occured while parsing the
addresses",e);
=======================================
---
/trunk/servers/sip-servlets/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/TestSipListener.java
Mon Dec 20 14:08:02 2010
+++
/trunk/servers/sip-servlets/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/TestSipListener.java
Mon Jan 3 05:51:04 2011
@@ -1101,6 +1101,9 @@
Thread.sleep(getTimeToWaitBetweenProvisionnalResponse());
Response response =
protocolObjects.messageFactory.createResponse(
provisionalResponseToSend,
request);
+ if(response.getStatusCode() == 183) {
+ response.setReasonPhrase("different" +
System.nanoTime());
+ }
if(provisionalResponseToSend >= Response.TRYING &&
provisionalResponseToSend < Response.OK) {
ToHeader toHeader = (ToHeader)
response.getHeader(ToHeader.NAME);
if(provisionalResponseToSend != Response.TRYING && toHeader.getTag()
== null) {
=======================================
---
/trunk/servers/sip-servlets/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistSipServletTest.java
Tue Dec 28 18:56:39 2010
+++
/trunk/servers/sip-servlets/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistSipServletTest.java
Mon Jan 3 05:51:04 2011
@@ -17,6 +17,7 @@
package org.mobicents.servlet.sip.testsuite.simple;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -168,6 +169,37 @@
assertTrue("sipSessionReadyToInvalidate",
allMessagesContent.contains("sipSessionReadyToInvalidate"));
assertTrue("sipAppSessionReadyToInvalidate",
allMessagesContent.contains("sipAppSessionReadyToInvalidate"));
}
+
+ public void testShootistEarlyMediaChange() throws Exception {
+// receiver.sendInvite();
+ receiverProtocolObjects =new ProtocolObjects(
+ "sender", "gov.nist", TRANSPORT, AUTODIALOG,
null, null, null);
+
+ LinkedList<Integer> responses = new LinkedList<Integer>();
+ responses.add(180);
+ responses.add(183);
+ responses.add(183);
+ responses.add(183);
+ receiver = new TestSipListener(5080, 5070, receiverProtocolObjects,
false);
+
+ receiver.setProvisionalResponsesToSend(responses);
+ receiver.setWaitForCancel(true);
+ SipProvider senderProvider = receiver.createProvider();
+
+ senderProvider.addSipListener(receiver);
+
+ receiverProtocolObjects.start();
+ tomcat.startTomcat();
+ deployApplication("cancel", "true");
+ Thread.sleep(DIALOG_TIMEOUT + TIMEOUT);
+ assertTrue(receiver.isCancelReceived());
+ List<String> allMessagesContent =
receiver.getAllMessagesContent();
+
+ assertTrue("earlyMedia",
receiver.getMessageRequest().getHeader("EarlyMediaResponses").toString().contains("3"));
+ assertTrue(allMessagesContent.size() >= 2);
+ assertTrue("sipSessionReadyToInvalidate",
allMessagesContent.contains("sipSessionReadyToInvalidate"));
+ assertTrue("sipAppSessionReadyToInvalidate",
allMessagesContent.contains("sipAppSessionReadyToInvalidate"));
+ }
public void testShootistSetContact() throws Exception {
// receiver.sendInvite();