if (!resp487.getSessionImpl().hasNoToTag()) {
Header to = resp487.getRawHeader(Header.TO);
Header toC = resp200.getRawHeader(Header.TO);
try {
Address adr = to.getAddressValue();
((AddressImpl) adr).setReadOnly(false);
adr.setParameter(AddressImpl.TAG_PARAM,
resp487.getSessionImpl().getToTag());
((AddressImpl) adr).setReadOnly(true);
Address adrC = toC.getAddressValue();
((AddressImpl) adrC).setReadOnly(false);
adrC.setParameter(AddressImpl.TAG_PARAM,
resp487.getSessionImpl().getToTag());
((AddressImpl) adrC).setReadOnly(true);
} catch (ServletParseException e) {
throw new IllegalStateException(
"Parse problem of To Header");
}
}
/**
* Since the resp487.popDispatcher().dispatch(resp487) does
* not go though the FSM, instead goes directly to DialogManager,
* the updateSipSessionState was never called.
*
* Hence, we need to call updateSipSessionState from here
* so that the session is marked for readyToInvalidate.
*/
resp487.getSessionImpl().updateSipSessionState(resp487, uas.getType());
resp487.popDispatcher().dispatch(resp487);
m_INVITE.setSentResponse(resp487.getStatus());
resp200.popDispatcher().dispatch(resp200);
} else if (method.equals("UPDATE")) {
if (!req.getSessionImpl().setUpdateOngoing()) {
resp = req.createTerminatingResponse(500);
resp.setHeader("Retry-After", "5");
}
}
// Can't sent response on ACK, cf
// SipServletResponseImpl.populateResponse()
else if (!method.equals("PRACK") && !method.equals("ACK")) {
// Forbidden
resp = req.createTerminatingResponse(403);
}
break;
}
case TRYING_UAS: {
if (method.equals("CANCEL")) {
m_State = TERMINATED_UAS;
// lets inform that this session is ending
uas.removeDialogSession(method, null);
// 200 OK
SipServletResponseImpl resp200 = req.createTerminatingResponse(200);
// Request Terminated
SipServletResponseImpl resp487 = m_INVITE.createTerminatingResponse(487);
// lets respond 200 CANCEL and 487 INVITE
if (!resp487.getSessionImpl().hasNoToTag()) {
Header to = resp487.getRawHeader(Header.TO);
Header toC = resp200.getRawHeader(Header.TO);
try {
Address adr = to.getAddressValue();
((AddressImpl) adr).setReadOnly(false);
adr.setParameter(AddressImpl.TAG_PARAM,
resp487.getSessionImpl().getToTag());
((AddressImpl) adr).setReadOnly(true);
Address adrC = toC.getAddressValue();
((AddressImpl) adrC).setReadOnly(false);
adrC.setParameter(AddressImpl.TAG_PARAM,
resp487.getSessionImpl().getToTag());
((AddressImpl) adrC).setReadOnly(true);
} catch (ServletParseException e) {
throw new IllegalStateException(
"Parse problem of To Header");
}
}
resp487.popDispatcher().dispatch(resp487);
m_INVITE.setSentResponse(resp487.getStatus());
resp200.popDispatcher().dispatch(resp200);
} else if (method.equals("UPDATE")) {
if (!req.getSessionImpl().setUpdateOngoing()) {
resp = req.createTerminatingResponse(500);
resp.setHeader("Retry-After", "5");
}
}
// Can't sent response on ACK, cf
// SipServletResponseImpl.populateResponse()
else if (!method.equals("ACK")) {
// Forbidden
resp = req.createTerminatingResponse(403);
}
break;
}
case CONFIRMED_UAS: {
if (method.equals("ACK")) {
// Lets stop the timer which triggers re-sending of 200
// (RFC 3261 13.3.1)
if (m_TimerShort != null) {
m_TimerShort.cancel();
m_TimerShort = null;
}
if (m_TimerLong != null) {
m_TimerLong.cancel();
m_TimerLong = null;
}
m_State = RUNNING;
//dereference to release memory
m_RetransmitResponse = null;
} else if (method.equals("UPDATE")) {
if (!req.getSessionImpl().setUpdateOngoing()) {
resp = req.createTerminatingResponse(500);
resp.setHeader("Retry-After", "5");
}
} else if (method.equals("BYE")) {
// HH20098
// Lets stop the timer which triggers re-sending of 200
// (RFC 3261 13.3.1)
if (m_TimerShort != null) {
m_TimerShort.cancel();
m_TimerShort = null;
}
if (m_TimerLong != null) {
m_TimerLong.cancel();
m_TimerLong = null;
}
m_State = CLOSING_UAS;
} else if (method.equals("CANCEL")) {
resp = req.createTerminatingResponse(481);
} else if (method.equals("INVITE")) {
resp = req.createTerminatingResponse(491);
} else if (!method.equals("PRACK")) {
resp = req.createTerminatingResponse(403);
}
break;
}
case TERMINATED_UAS: {
if (method.equals("CANCEL")) {
// Forbidden
resp = req.createTerminatingResponse(403);
}
// Can't sent response on ACK, cf
// SipServletResponseImpl.populateResponse()
else if (!method.equals("ACK")) {
// Request Terminated
resp = req.createTerminatingResponse(487);
}
break;
}
case RUNNING: {
if (method.equals("BYE")) {
m_State = CLOSING_UAS;
} else if (method.equals("INVITE")) {
m_State = RE_INVITE_UAS;
m_INVITE = req;
} else if (method.equals("PRACK")) {
// A 1XX is pending and a 200OK(INVITE) have been sent before
// receiving
// the PRACK request.
String rackPrack = req.getHeader(Header.RACK);
// The Rack Header in the PRACK must match the RSeq + CSeq of the
// prov response
if (!((rackPrack != null) && (m_Rack != null) &&
m_Rack.equalsIgnoreCase(rackPrack))) {
resp = req.createTerminatingResponse(481);
}
} else if (method.equals("UPDATE")) {
if (!req.getSessionImpl().setUpdateOngoing()) {
resp = req.createTerminatingResponse(500);
resp.setHeader("Retry-After", "5");
}
}
// Can't sent response on ACK, cf
// SipServletResponseImpl.populateResponse()
else {
isInvokeServlet = false;
if (!method.equals("ACK")) {
// Forbidden
resp = req.createTerminatingResponse(403);
}
}
break;
}
case RE_INVITE_INITIAL_UAC:
case RE_INVITE_TRYING_UAC:
case RE_INVITE_EARLY_UAC: {
if (method.equals("BYE")) {
m_State = CLOSING_UAS;
} else if (method.equals("INVITE")) {
// OK, a remote INVITE arrived while processing
// a locally generated INVITE already
m_State = RUNNING;
// need to immediately respond with a pending response
resp = req.createTerminatingResponse(491);
}
// Can't sent response on ACK, cf
// SipServletResponseImpl.populateResponse()
else if (!method.equals("PRACK") && !method.equals("UPDATE") &&
!method.equals("ACK")) {
resp = req.createTerminatingResponse(403);
}
break;
}
case RE_INVITE_UAS: {
if (method.equals("BYE")) {
m_State = CLOSING_UAS;
} else if (method.equals("INVITE")) {
// OK, the second remote INVITE
// respond with an 500 error
// TODO add Retry-After Header
// random value between 0-10s
resp = req.createTerminatingResponse(500);
} else if (method.equals("UPDATE")) {
if (!req.getSessionImpl().setUpdateOngoing()) {
resp = req.createTerminatingResponse(500);
resp.setHeader("Retry-After", "5");
}
} else if (method.equals("CANCEL")) {
m_State = RUNNING;
// lets inform that this session is ending
uas.removeDialogSession(method, null);
// 200 OK
SipServletResponseImpl resp200 = req.createTerminatingResponse(200);
// Request Terminated
SipServletResponseImpl resp487 = m_INVITE.createTerminatingResponse(487);
// lets respond 200 CANCEL and 487 INVITE
if (!resp487.getSessionImpl().hasNoToTag()) {
Header to = resp487.getRawHeader(Header.TO);
try {
Address adr = to.getAddressValue();
((AddressImpl) adr).setReadOnly(false);
adr.setParameter(AddressImpl.TAG_PARAM,
resp487.getSessionImpl().getToTag());
((AddressImpl) adr).setReadOnly(true);
} catch (ServletParseException e) {
throw new IllegalStateException(
"Parse problem of To Header");