* If the Request-URI of the request contains an maddr parameter,
* the Request-URI MUST be placed into the target set as the only
* target URI, and the proxy MUST proceed to Section 16.6.
*/
URI requestURI = msg.getRequestURI();
if (requestURI.isSipURI())
{
SipURI requestSipURI = (SipURI) requestURI;
if (requestSipURI.getMAddrParam() != null)
{
uris.clear();
uris.add(requestURI);
if (jiplet.isDebugEnabled() == true)
jiplet
.debug("While proxying a request, "
+ " the only target is the Request-URI (mAddr parameter)");
// 4. Forward the request
RequestForwarding forwarder = new RequestForwarding(jiplet,
this, request,
serverTransaction, stateful, addRecordRoute);
forwarder.forwardRequest(uris);
return;
}
}
if (stateful == true)
{
// Forward to next hop but dont reply OK right away for the
// BYE. Bye is end-to-end not hop by hop!
if (msg.getMethod().equals(Request.BYE))
{
if (serverTransaction == null)
{
if (jiplet.isDebugEnabled() == true)
jiplet
.debug("While proxying a request, null server transaction for BYE");
return;
}
Dialog d = serverTransaction.getDialog();
TransactionsMapping transactionsMapping = jiplet.getDialog(
d, true).getTransactionsMapping();
Dialog peerDialog = transactionsMapping
.getPeerDialog(serverTransaction);
Request clonedRequest = (Request) msg.clone();
FromHeader from = (FromHeader) clonedRequest
.getHeader(FromHeader.NAME);
from.removeParameter("tag");
ToHeader to = (ToHeader) clonedRequest
.getHeader(ToHeader.NAME);
to.removeParameter("tag");
if (peerDialog.getState() != null)
{
JipletDialog clientDialog = jiplet.getDialog(peerDialog, false);
SipProvider clientProvider = clientDialog.getSipProvider();
ListeningPoint lp = clientProvider.getListeningPoints()[0];
// TODO, need to save the right transport - save LP instead of SipProvider?
// (in JipletDialog)
ViaHeader via = jiplet.getHeaderFactory().createViaHeader(lp.getIPAddress(),
lp.getPort(), lp.getTransport(), null);
clonedRequest.addHeader(via);
ClientTransaction newct = clientProvider
.getNewClientTransaction(clonedRequest);
transactionsMapping
.addMapping(serverTransaction, newct);
peerDialog.sendRequest(newct);
jiplet.registerForResponse(clonedRequest, 60000L);
return;
}
else
{
// the peer dialog is not yet established so bail out.
// this is a client error - client is sending BYE
// before dialog establishment.
jiplet
.warn("While proxying a SIP request, bad dialog state - BYE dropped");
return;
}
}
// NEW CODE added by Amit to handle ACK and CANCEL
else if (msg.getMethod().equals(Request.ACK))
{
if (serverTransaction == null)
{
if (jiplet.isDebugEnabled() == true)
jiplet
.debug("While proxying an ACK request, null server transaction");
return;
}
Dialog d = serverTransaction.getDialog();
TransactionsMapping transactionsMapping = jiplet.getDialog(
d, true).getTransactionsMapping();
Dialog peerDialog = transactionsMapping
.getPeerDialog(serverTransaction);
Request clonedRequest = (Request) msg.clone();
if (peerDialog.getState() != null)
{
peerDialog.sendAck(clonedRequest);
}
return;
}
else if (msg.getMethod().equals(Request.CANCEL))
{
if (serverTransaction == null)
{
if (jiplet.isDebugEnabled() == true)
jiplet
.debug("While proxying a CANCEL request, null server transaction for BYE");
return;
}
Dialog d = serverTransaction.getDialog();
JipletDialog jd = jiplet.getDialog(d, true);
TransactionsMapping transactionsMapping = jd
.getTransactionsMapping();
Vector transactions = transactionsMapping
.getClientTransactions((ServerTransaction) jd
.getAttribute("firstTransaction"));
if (transactions == null || transactions.isEmpty())
{
return;
}
for (Enumeration en = transactions.elements(); en
.hasMoreElements();)
{
ClientTransaction ct = (ClientTransaction) en
.nextElement();
// check if the client transaction can be canceled.
if (ct.getState().equals(TransactionState.COMPLETED)
|| ct.getState().equals(
TransactionState.TERMINATED))
{
continue;
}
JipletDialog clientJipletDialog = (JipletDialog) ct.getDialog().getApplicationData();
if (clientJipletDialog != null)
{
ClientTransaction client = clientJipletDialog.getSipProvider().getNewClientTransaction(ct.createCancel());
client.sendRequest();
}
}
}
// END NEW CODE
}
/*
* If the target set for the request has not been predetermined as
* described above, this implies that the element is responsible for
* the domain in the Request-URI, and the element MAY use whatever
* mechanism it desires to determine where to send the request. ...
* When accessing the location service constructed by a registrar,
* the Request-URI MUST first be canonicalized as described in
* Section 10.3 before being used as an index.
*/
if (requestURI.isSipURI())
{
SipURI requestSipURI = (SipURI) requestURI;
Iterator iterator = requestSipURI.getParameterNames();
if (jiplet.isDebugEnabled() == true)
jiplet.debug("While proxying a request, we canonicalized"
+ " the request-URI");
while (iterator != null && iterator.hasNext())
{
String name = (String) iterator.next();
requestSipURI.removeParameter(name);
}
}
// We fork only INVITE
if (uris.size() > 1 && !msg.getMethod().equals(Request.INVITE))
{
if (jiplet.isDebugEnabled() == true)
jiplet.debug("While proxying a request, the request "
+ " to fork is not an INVITE, so we will process"
+ " it with the first target as the only target.");
URI uri = (URI) uris.get(0);
uris.clear();
uris.add(uri);
// 4. Forward the request to the target:
RequestForwarding forwarder = new RequestForwarding(jiplet,