Centralizes use of Contact header generation. Moves parts of incoming call handling to CallSipImpl.

cusax-fix
Emil Ivov 17 years ago
parent bcf58dea65
commit 57d5c4961e

@ -12,7 +12,7 @@
import javax.sip.*;
import javax.sip.address.*;
import javax.sip.address.URI;
import javax.sip.address.URI;//disambiguates java.net.URI
import javax.sip.header.*;
import javax.sip.message.*;
@ -450,6 +450,60 @@ private CallPeerSipImpl createCallPeerFor(
return callPeer;
}
/**
* Processes an incoming INVITE that is meant to replace an existing
* <tt>CallPeerSipImpl</tt> that is participating in this call. Typically
* this would happen as a result of an attended transfer.
*
* @param jainSipProvider the JAIN-SIP <tt>SipProvider</tt> that received
* the request.
* @param serverTransaction the transaction containing the INVITE request.
* @param callPeerToReplace a reference to the <tt>CallPeer</tt> that this
* INVITE is trying to replace.
*/
public void processReplacingInvite(SipProvider jainSipProvider,
ServerTransaction serverTransaction,
CallPeerSipImpl callPeerToReplace)
{
Request request = serverTransaction.getRequest();
CallPeerSipImpl newCallPeer
= createCallPeerFor(serverTransaction, jainSipProvider);
try
{
answerCallPeer(newCallPeer);
}
catch (OperationFailedException ex)
{
logger.error(
"Failed to auto-answer the referred call peer "
+ newCallPeer, ex);
/*
* RFC 3891 says an appropriate error response MUST be returned
* and callPeerToReplace must be left unchanged.
*/
//TODO should we send a response here?
return;
}
//we just accepted the new peer and if we got here then it went well
//now let's hangup the other call.
try
{
hangupCallPeer(callPeerToReplace);
}
catch (OperationFailedException ex)
{
logger.error("Failed to hangup the referer "
+ callPeerToReplace, ex);
callPeerToReplace.setState(
CallPeerState.FAILED, "Internal Error: " + ex);
}
}
/**
* Creates a new call and sends a RINGING response.
*
@ -460,62 +514,87 @@ private CallPeerSipImpl createCallPeerFor(
public CallPeerSipImpl processInvite(SipProvider jainSipProvider,
ServerTransaction serverTransaction)
{
Request request = serverTransaction.getRequest();
Request invite = serverTransaction.getRequest();
CallPeerSipImpl peer
= createCallPeerFor(serverTransaction, jainSipProvider);
return peer;
}
public void processReInvite(SipProvider jainSipProvider,
ServerTransaction serverTransaction)
{
Request request = serverTransaction.getRequest();
}
public void processReplacingInvite(SipProvider jainSipProvider,
ServerTransaction serverTransaction)
{
Request request = serverTransaction.getRequest();
// extract the SDP description.
// beware: SDP description may be in ACKs so it could be that there's
// nothing here - bug report Laurent Michel
ContentLengthHeader cl = invite.getContentLength();
if (cl != null && cl.getContentLength() > 0)
{
peer.setSdpDescription(new String(invite.getRawContent()));
}
if ((statusCode == Response.OK) && (callPeerToReplace != null))
//send a ringing reply
Response response = null;
try
{
boolean sayBye = false;
response = this.messageFactory.createResponse(Response.RINGING, invite);
try
{
answerCallPeer(callPeer);
sayBye = true;
}
catch (OperationFailedException ex)
{
logger.error(
"Failed to auto-answer the referred call peer "
+ callPeer, ex);
/*
* RFC 3891 says an appropriate error response MUST be returned
* and callPeerToReplace must be left unchanged.
*/
}
if (sayBye)
//set the contact header
response.setHeader(getProtocolProvider()
.getContactHeaderForResponse(invite));
//add the SDP
if (statusCode == Response.OK)
{
try
{
hangupCallPeer(callPeerToReplace);
attachSDP(callPeer, response);
}
catch (OperationFailedException ex)
{
logger.error("Failed to hangup the referer "
+ callPeerToReplace, ex);
callPeerToReplace.setState(
CallPeerState.FAILED, "Internal Error: " + ex);
logger.error("Error while trying to send response "
+ response, ex);
callPeer.setState(CallPeerState.FAILED,
"Internal Error: " + ex.getMessage());
return;
}
}
// Even if there was a failure, we cannot just send Response.OK.
}
catch (ParseException ex)
{
logger.error("Error while trying to send a response", ex);
callPeer.setState(CallPeerState.FAILED,
"Internal Error: " + ex.getMessage());
return;
}
try
{
logger.trace("will send " + statusCode + " response: ");
serverTransaction.sendResponse(response);
logger.debug("sent a " + statusCode + " response: "
+ response);
}
catch (Exception ex)
{
logger.error("Error while trying to send a request", ex);
callPeer.setState(CallPeerState.FAILED,
"Internal Error: " + ex.getMessage());
return;
}
if (statusCode == Response.OK)
{
try
{
setMediaFlagsForPeer(callPeer, response);
}
catch (OperationFailedException ex)
{
logger.error("Error after sending response " + response, ex);
}
}
return peer;
}
public void processReInvite(SipProvider jainSipProvider,
ServerTransaction serverTransaction)
{
Request request = serverTransaction.getRequest();
}
}

@ -277,11 +277,11 @@ else if (on)
* specified call peer with the sent invite
* @throws OperationFailedException
*/
void sendInviteRequest(CallPeerSipImpl sipPeer,
String sdpOffer) throws OperationFailedException
void sendInviteRequest(CallPeerSipImpl sipPeer, String sdpOffer)
throws OperationFailedException
{
Dialog dialog = sipPeer.getDialog();
Request invite = createRequest(dialog, Request.INVITE);
Request invite = messageFactory.createRequest(dialog, Request.INVITE);
try
{
@ -311,8 +311,10 @@ void sendInviteRequest(CallPeerSipImpl sipPeer,
* <tt>request</tt> is to be sent
* @throws OperationFailedException
*/
private void sendRequest(SipProvider sipProvider, Request request,
Dialog dialog) throws OperationFailedException
private void sendRequest(SipProvider sipProvider,
Request request,
Dialog dialog)
throws OperationFailedException
{
ClientTransaction clientTransaction = null;
try
@ -1223,6 +1225,7 @@ private void processInvite(SipProvider sourceProvider,
}
else
{
//this is a reINVITE.
callSipImpl.processReInvite(sourceProvider, serverTransaction);
}
@ -1244,7 +1247,7 @@ private void originalProcessInvite(SipProvider sourceProvider,
Dialog dialog = serverTransaction.getDialog();
CallPeerSipImpl callPeer =
activeCallsRepository.findCallPeer(dialog);
int statusCode;
int statusCode = 0;
CallPeerSipImpl callPeerToReplace = null;
if (callPeer == null)
@ -1288,29 +1291,24 @@ private void originalProcessInvite(SipProvider sourceProvider,
// Send statusCode
//...
Response response = null;
try
{
response = protocolProvider.getMessageFactory()
.createResponse(statusCode, invite);
protocolProvider.attachToTag(response, dialog);
// set our display name
((ToHeader) response.getHeader(ToHeader.NAME)).getAddress()
.setDisplayName(protocolProvider.getOurDisplayName());
// extract our intended destination which should be in the from
Address callerAddress =
((FromHeader) response.getHeader(FromHeader.NAME))
.getAddress();
response.setHeader(protocolProvider
.getContactHeader(callerAddress));
.getContactHeaderForResponse(invite));
//add the SDP
if (statusCode == Response.OK)
{
try
{
processInviteSendingResponse(callPeer, response);
attachSDP(callPeer, response);
}
catch (OperationFailedException ex)
{
@ -1331,9 +1329,9 @@ private void originalProcessInvite(SipProvider sourceProvider,
}
try
{
logger.trace("will send " + statusCodeString + " response: ");
logger.trace("will send " + statusCode + " response: ");
serverTransaction.sendResponse(response);
logger.debug("sent a " + statusCodeString + " response: "
logger.debug("sent a " + statusCode + " response: "
+ response);
}
catch (Exception ex)
@ -1348,7 +1346,7 @@ private void originalProcessInvite(SipProvider sourceProvider,
{
try
{
processInviteSentResponse(callPeer, response);
setMediaFlagsForPeer(callPeer, response);
}
catch (OperationFailedException ex)
{
@ -1370,8 +1368,8 @@ private void originalProcessInvite(SipProvider sourceProvider,
* @throws OperationFailedException
* @throws ParseException
*/
private void processInviteSendingResponse(CallPeer peer,
Response response) throws OperationFailedException, ParseException
private void attachSDP(CallPeer peer, Response response)
throws OperationFailedException, ParseException
{
/*
* At the time of this writing, we're only getting called because a
@ -1416,8 +1414,8 @@ private void processInviteSendingResponse(CallPeer peer,
* @throws OperationFailedException
* @throws ParseException
*/
private void processInviteSentResponse(CallPeer peer,
Response response) throws OperationFailedException
private void setMediaFlagsForPeer(CallPeer peer, Response response)
throws OperationFailedException
{
/*
* At the time of this writing, we're only getting called because a
@ -1665,11 +1663,9 @@ private void processCancel(ServerTransaction serverTransaction,
ServerTransaction inviteTran = (ServerTransaction) tran;
Request invite = callPeer.getFirstTransaction().getRequest();
Response requestTerminated =
protocolProvider.getMessageFactory().createResponse(
Response.REQUEST_TERMINATED, invite);
protocolProvider.attachToTag(requestTerminated, callPeer
.getDialog());
Response requestTerminated = protocolProvider.getMessageFactory()
.createResponse(Response.REQUEST_TERMINATED, invite);
inviteTran.sendResponse(requestTerminated);
if (logger.isDebugEnabled())
logger.debug("sent request terminated response:\n"
@ -1724,10 +1720,8 @@ private void processRefer(ServerTransaction serverTransaction,
Response accepted = null;
try
{
accepted =
protocolProvider.getMessageFactory().createResponse(
accepted = protocolProvider.getMessageFactory().createResponse(
Response.ACCEPTED, referRequest);
protocolProvider.attachToTag(accepted, dialog);
}
catch (ParseException ex)
{
@ -2069,7 +2063,7 @@ private void sendReferNotifyRequest(Dialog dialog,
String subscriptionState, String reasonCode, Object content,
SipProvider sipProvider) throws OperationFailedException
{
Request notify = createRequest(dialog, Request.NOTIFY);
Request notify = messageFactory.createRequest(dialog, Request.NOTIFY);
HeaderFactory headerFactory = protocolProvider.getHeaderFactory();
// Populate the request.
@ -2088,8 +2082,8 @@ private void sendReferNotifyRequest(Dialog dialog,
SubscriptionStateHeader ssHeader = null;
try
{
ssHeader =
headerFactory.createSubscriptionStateHeader(subscriptionState);
ssHeader = headerFactory
.createSubscriptionStateHeader(subscriptionState);
if (reasonCode != null)
ssHeader.setReasonCode(reasonCode);
}
@ -2105,8 +2099,8 @@ private void sendReferNotifyRequest(Dialog dialog,
ContentTypeHeader ctHeader = null;
try
{
ctHeader =
headerFactory.createContentTypeHeader("message", "sipfrag");
ctHeader = headerFactory
.createContentTypeHeader("message", "sipfrag");
}
catch (ParseException ex)
{
@ -2379,8 +2373,7 @@ private void sayBusyHere(CallPeerSipImpl callPeer)
try
{
busyHere = messageFactory.createResponse(
Response.BUSY_HERE, request);
protocolProvider.attachToTag(busyHere, callPeer.getDialog());
Response.BUSY_HERE, request);
}
catch (ParseException ex)
{
@ -2571,7 +2564,6 @@ private Response createOKResponse(Request request, Dialog containingDialog)
throws ParseException
{
Response ok = messageFactory.createResponse(Response.OK, request);
protocolProvider.attachToTag(ok, containingDialog);
return ok;
}

@ -1126,12 +1126,14 @@ public ContactHeader getContactHeader(SipURI intendedDestination)
Address contactAddress = addressFactory.createAddress( contactURI );
String ourDisplayName = getOurDisplayName();
if (ourDisplayName != null)
{
contactAddress.setDisplayName(ourDisplayName);
}
registrationContactHeader = headerFactory.createContactHeader(
contactAddress);
logger.debug("generated contactHeader:"
+ registrationContactHeader);
}
@ -2000,8 +2002,9 @@ public UserAgentHeader getSipCommUserAgentHeader()
* Generates a ToTag and attaches it to the to header of <tt>response</tt>.
*
* @param response the response that is to get the ToTag.
* @param containingDialog the Dialog instance that is to extract a unique
* Tag value (containingDialog.hashCode())
* @param containingDialog the <tt>Dialog</tt> instance that the response
* would be sent in or <tt>null</tt> if we are not aware of the
* <tt>Dialog</tt> when calling this method.
*/
public void attachToTag(Response response, Dialog containingDialog)
{
@ -2011,7 +2014,8 @@ public void attachToTag(Response response, Dialog containingDialog)
return;
}
if(containingDialog.getLocalTag() != null)
if( containingDialog != null
&& containingDialog.getLocalTag() != null)
{
logger.debug("We seem to already have a tag in this dialog. "
+"Returning");

@ -6,6 +6,7 @@
*/
package net.java.sip.communicator.impl.protocol.sip;
import gov.nist.javax.sip.header.*;
import gov.nist.javax.sip.header.extensions.*;
import java.text.*;
@ -253,6 +254,27 @@ private Message attachScSpecifics(Message message)
SipApplicationData.setApplicationData(message,
SipApplicationData.KEY_SERVICE, this.protocolProvider);
//the jain-sip semantics allow the application to "forget" attaching a
//To tag to a response so let's make sure we do this here
if(message instanceof Response)
{
FromHeader from = (FromHeader)message.getHeader(From.NAME);
String fromTag = (from == null) ? null : from.getTag();
Response response = (Response)message;
//if there's a from tag and this is a non-failure response,
//then we are adding a to tag.
if(fromTag != null && fromTag.trim().length() > 0
&& response.getStatusCode() > 100
&& response.getStatusCode() < 300)
{
protocolProvider.attachToTag(response, null);
}
}
//add a contact header.
attachContactHeader(message);
// User Agent
UserAgentHeader userAgentHeader
= protocolProvider.getSipCommUserAgentHeader();
@ -267,7 +289,26 @@ private Message attachScSpecifics(Message message)
return message;
}
//---------------- higher level methods ----------------------------------
/**
* The method tries to determine an address that would be reachable by the
* destination of <tt>message</tt> and then creates a <tt>ContactHeader</tt>
* out of it and attaches it to the <tt>message</tt>. The method takes into
* account both <tt>Request</tt>s and <tt>Response</tt>s. The method
* is meant to be used only for messages that have been otherwise
* initialized (in particular the Request URI in requests or the Via
* headers in responses.).
*
* @param message the message that we'd like to attach a
* <tt>ContactHeader</tt> to.
*
* @return a reference to the <tt>message</tt> that was also passed as
* a parameter in order to allow for more agility when using the method.
*/
private Message attachContactHeader(Message message)
{
//creates a Contact header
}
/**
* Creates a new {@link Request} of a specific method which is to be sent in
* a specific <tt>Dialog</tt> and populates its generally-necessary
@ -298,8 +339,6 @@ public Request createRequest(Dialog dialog, String method)
OperationFailedException.INTERNAL_ERROR, ex, logger);
}
attachScSpecifics(request);
//override the via and contact headers as jain-sip is generating one
//from the listening point which is 0.0.0.0 or ::0
ArrayList<ViaHeader> viaHeaders
@ -309,22 +348,28 @@ public Request createRequest(Dialog dialog, String method)
request.setHeader(protocolProvider
.getContactHeader(dialog.getRemoteParty()));
//now that we've set the Via headers right, we can attach our SC
//specifics
attachScSpecifics(request);
// We have a dialog here so let's try and pre-authenticate the request.
preAuthenticateRequest(request);
return request;
}
//---------------- higher level methods ----------------------------------
/**
* Creates an invite request destined for <tt>callee</tt>.
*
* @param toAddress the sip address of the callee that the request is meant
* for.
* for.
*
* @return a newly created sip <tt>Request</tt> destined for
* <tt>callee</tt>.
*
* @return a newly created sip <tt>Request</tt> destined for <tt>callee</tt>
* .
* @throws OperationFailedException with the corresponding code if creating
* the request fails.
* the request fails.
* @throws IllegalArgumentException if <tt>toAddress</tt> does not appear
* to be a valid destination.
*/
@ -372,8 +417,7 @@ public Request createInviteRequest( Address toAddress)
try
{
// FromHeader
fromHeader =
headerFactory.createFromHeader(
fromHeader = headerFactory.createFromHeader(
protocolProvider.getOurSipAddress(toAddress), localTag);
// ToHeader

Loading…
Cancel
Save