diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicTelephonySipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicTelephonySipImpl.java index 6a5514781..4efc66648 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicTelephonySipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicTelephonySipImpl.java @@ -18,6 +18,7 @@ import javax.sip.header.*; import javax.sip.message.*; +import net.java.sip.communicator.impl.protocol.sip.util.*; import net.java.sip.communicator.service.media.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; @@ -174,20 +175,9 @@ private synchronized CallSipImpl createOutgoingCall(Address calleeAddress, } // create the invite request - Request invite; - try - { - invite = createInviteRequest(calleeAddress); - } - catch (IllegalArgumentException exc) - { - // encapsulate the illegal argument exception into an OpFailedExc - // so that the UI would notice it. - throw new OperationFailedException( - exc.getMessage(), - OperationFailedException.ILLEGAL_ARGUMENT, - exc); - } + Request invite = JainSipTelephonyHelper + .createInviteRequest(calleeAddress, protocolProvider); + // check whether there's a cached authorization header for this // call id and if so - attach it to the request. @@ -1355,170 +1345,7 @@ public boolean processDialogTerminated( return true; } - /** - * Creates an invite request destined for callee. - * - * @param toAddress the sip address of the callee that the request is meant - * for. - * @return a newly created sip Request destined for callee - * . - * @throws OperationFailedException with the corresponding code if creating - * the request fails. - * @throws IllegalArgumentException if toAddress does not appear - * to be a valid destination. - */ - private Request createInviteRequest(Address toAddress) - throws OperationFailedException, IllegalArgumentException - { - // Call ID - CallIdHeader callIdHeader = - protocolProvider.getDefaultJainSipProvider().getNewCallId(); - - // CSeq - HeaderFactory headerFactory = protocolProvider.getHeaderFactory(); - CSeqHeader cSeqHeader = null; - try - { - cSeqHeader = headerFactory.createCSeqHeader(1l, Request.INVITE); - } - catch (InvalidArgumentException ex) - { - // Shouldn't happen - throwOperationFailedException("An unexpected erro occurred while" - + "constructing the CSeqHeadder", - OperationFailedException.INTERNAL_ERROR, ex); - } - catch (ParseException exc) - { - // shouldn't happen - throwOperationFailedException("An unexpected erro occurred while" - + "constructing the CSeqHeadder", - OperationFailedException.INTERNAL_ERROR, exc); - } - - // ReplacesHeader - Header replacesHeader = stripReplacesHeader(toAddress); - - // FromHeader - String localTag = ProtocolProviderServiceSipImpl.generateLocalTag(); - FromHeader fromHeader = null; - ToHeader toHeader = null; - try - { - // FromHeader - fromHeader = - headerFactory.createFromHeader( - protocolProvider.getOurSipAddress(toAddress), localTag); - - // ToHeader - toHeader = headerFactory.createToHeader(toAddress, null); - } - catch (ParseException ex) - { - // these two should never happen. - throwOperationFailedException("An unexpected erro occurred while" - + "constructing the ToHeader", - OperationFailedException.INTERNAL_ERROR, ex); - } - - // ViaHeaders - ArrayList viaHeaders = - protocolProvider.getLocalViaHeaders(toAddress); - - // MaxForwards - MaxForwardsHeader maxForwards = protocolProvider.getMaxForwardsHeader(); - - // Contact - ContactHeader contactHeader - = protocolProvider.getContactHeader(toHeader.getAddress()); - - Request invite = null; - try - { - invite = - protocolProvider.getMessageFactory().createRequest( - toHeader.getAddress().getURI(), Request.INVITE, - callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, - maxForwards); - } - catch (ParseException ex) - { - // shouldn't happen - throwOperationFailedException("Failed to create invite Request!", - OperationFailedException.INTERNAL_ERROR, ex); - } - - // User Agent - UserAgentHeader userAgentHeader = - protocolProvider.getSipCommUserAgentHeader(); - if (userAgentHeader != null) - invite.addHeader(userAgentHeader); - - // add the contact header. - invite.addHeader(contactHeader); - - // Add the ReplacesHeader if any. - if (replacesHeader != null) - { - invite.setHeader(replacesHeader); - } - - return invite; - } - - /** - * Returns the ReplacesHeader contained, if any, in the - * URI of a specific Address after removing it - * from there. - * - * @param address the Address which is to have its - * URI examined and modified - * @return a Header which represents the Replaces header - * contained in the URI of the specified - * address; null if no such header is - * present - */ - private Header stripReplacesHeader(Address address) - throws OperationFailedException - { - javax.sip.address.URI uri = address.getURI(); - Header replacesHeader = null; - - if (uri.isSipURI()) - { - SipURI sipURI = (SipURI) uri; - String replacesHeaderValue = sipURI.getHeader(ReplacesHeader.NAME); - - if (replacesHeaderValue != null) - { - for (Iterator headerNameIter = sipURI.getHeaderNames(); - headerNameIter.hasNext();) - { - if (ReplacesHeader.NAME.equals(headerNameIter.next())) - { - headerNameIter.remove(); - break; - } - } - - try - { - replacesHeader = - protocolProvider.getHeaderFactory().createHeader( - ReplacesHeader.NAME, replacesHeaderValue); - } - catch (ParseException ex) - { - throw new OperationFailedException( - "Failed to create ReplacesHeader from " - + replacesHeaderValue, - OperationFailedException.INTERNAL_ERROR, ex); - } - } - } - return replacesHeader; - } /** * Creates a new call and sends a RINGING response. 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 4fdeab490..edc6b4cdc 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java @@ -1025,8 +1025,6 @@ public ContactHeader getContactHeader(Address intendedDestination) * this contact header to. * * @return a Contact header based upon a local inet address. - * @throws OperationFailedException if we fail constructing the contact - * header. */ public ContactHeader getContactHeader(SipURI intendedDestination) { diff --git a/src/net/java/sip/communicator/impl/protocol/sip/util/JainSipTelephonyHelper.java b/src/net/java/sip/communicator/impl/protocol/sip/util/JainSipTelephonyHelper.java index 5a9768503..d562a9108 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/util/JainSipTelephonyHelper.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/util/JainSipTelephonyHelper.java @@ -6,8 +6,20 @@ */ package net.java.sip.communicator.impl.protocol.sip.util; +import gov.nist.javax.sip.header.extensions.*; + +import java.text.*; +import java.util.*; + +import javax.sip.*; +import javax.sip.address.*; +import javax.sip.header.*; import javax.sip.message.*; +import net.java.sip.communicator.impl.protocol.sip.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + /** * The class contains a number of utility methods dealing with construction of * messages related to telephony. @@ -16,6 +28,218 @@ */ public class JainSipTelephonyHelper { + private static final Logger logger + = Logger.getLogger(JainSipTelephonyHelper.class); + + /** + * Creates an invite request destined for callee. + * + * @param toAddress the sip address of the callee that the request is meant + * for. + * @param protocolProvider a reference to the protocol provider that is + * creating the request. + * + * @return a newly created sip Request destined for callee + * . + * @throws OperationFailedException with the corresponding code if creating + * the request fails. + * @throws IllegalArgumentException if toAddress does not appear + * to be a valid destination. + */ + public static Request createInviteRequest( + Address toAddress, + ProtocolProviderServiceSipImpl protocolProvider) + throws OperationFailedException, IllegalArgumentException + { + // Call ID + CallIdHeader callIdHeader = + protocolProvider.getDefaultJainSipProvider().getNewCallId(); + + // CSeq + HeaderFactory headerFactory = protocolProvider.getHeaderFactory(); + CSeqHeader cSeqHeader = null; + try + { + cSeqHeader = headerFactory.createCSeqHeader(1l, Request.INVITE); + } + catch (InvalidArgumentException ex) + { + // Shouldn't happen + throwOperationFailedException("An unexpected erro occurred while" + + "constructing the CSeqHeadder", + OperationFailedException.INTERNAL_ERROR, ex); + } + catch (ParseException exc) + { + // shouldn't happen + throwOperationFailedException("An unexpected erro occurred while" + + "constructing the CSeqHeadder", + OperationFailedException.INTERNAL_ERROR, exc); + } + + // ReplacesHeader + Header replacesHeader + = stripReplacesHeader(toAddress, protocolProvider); + + // FromHeader + String localTag = ProtocolProviderServiceSipImpl.generateLocalTag(); + FromHeader fromHeader = null; + ToHeader toHeader = null; + try + { + // FromHeader + fromHeader = + headerFactory.createFromHeader( + protocolProvider.getOurSipAddress(toAddress), localTag); + + // ToHeader + toHeader = headerFactory.createToHeader(toAddress, null); + } + catch (ParseException ex) + { + // these two should never happen. + throwOperationFailedException("An unexpected erro occurred while" + + "constructing the ToHeader", + OperationFailedException.INTERNAL_ERROR, ex); + } + + // ViaHeaders + ArrayList viaHeaders = + protocolProvider.getLocalViaHeaders(toAddress); + + // MaxForwards + MaxForwardsHeader maxForwards = protocolProvider.getMaxForwardsHeader(); + + // Contact + ContactHeader contactHeader = null; + try + { + contactHeader + = protocolProvider.getContactHeader(toHeader.getAddress()); + } + catch (IllegalArgumentException exc) + { + // encapsulate the illegal argument exception into an OpFailedExc + // so that the UI would notice it. + throw new OperationFailedException( + exc.getMessage(), + OperationFailedException.ILLEGAL_ARGUMENT, + exc); + } + + Request invite = null; + try + { + invite = + protocolProvider.getMessageFactory().createRequest( + toHeader.getAddress().getURI(), Request.INVITE, + callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, + maxForwards); + + } + catch (ParseException ex) + { + // shouldn't happen + throwOperationFailedException("Failed to create invite Request!", + OperationFailedException.INTERNAL_ERROR, ex); + } + + // User Agent + UserAgentHeader userAgentHeader = + protocolProvider.getSipCommUserAgentHeader(); + if (userAgentHeader != null) + invite.addHeader(userAgentHeader); + + // add the contact header. + invite.addHeader(contactHeader); + + // Add the ReplacesHeader if any. + if (replacesHeader != null) + { + invite.setHeader(replacesHeader); + } + + return invite; + } + + /** + * Returns the ReplacesHeader contained, if any, in the + * URI of a specific Address after removing it + * from there. + * + * @param address the Address which is to have its + * URI examined and modified + * @param protocolProvider a reference to the protocol provider that is + * creating the request. + * + * @return a Header which represents the Replaces header + * contained in the URI of the specified + * address; null if no such header is + * present + */ + private static Header stripReplacesHeader( + Address address, + ProtocolProviderServiceSipImpl protocolProvider) + throws OperationFailedException + { + javax.sip.address.URI uri = address.getURI(); + Header replacesHeader = null; + + if (uri.isSipURI()) + { + SipURI sipURI = (SipURI) uri; + String replacesHeaderValue = sipURI.getHeader(ReplacesHeader.NAME); + + if (replacesHeaderValue != null) + { + for (Iterator headerNameIter = sipURI.getHeaderNames(); + headerNameIter.hasNext();) + { + if (ReplacesHeader.NAME.equals(headerNameIter.next())) + { + headerNameIter.remove(); + break; + } + } + try + { + replacesHeader = + protocolProvider.getHeaderFactory().createHeader( + ReplacesHeader.NAME, replacesHeaderValue); + } + catch (ParseException ex) + { + throw new OperationFailedException( + "Failed to create ReplacesHeader from " + + replacesHeaderValue, + OperationFailedException.INTERNAL_ERROR, ex); + } + } + } + return replacesHeader; + } + /** + * Logs a specific message and associated Throwable cause as an + * error using the current Logger and then throws a new + * OperationFailedException with the message, a specific error code + * and the cause. + * + * @param message the message to be logged and then wrapped in a new + * OperationFailedException + * @param errorCode the error code to be assigned to the new + * OperationFailedException + * @param cause the Throwable that has caused the necessity to log + * an error and have a new OperationFailedException + * thrown + * @throws OperationFailedException + */ + private static void throwOperationFailedException(String message, + int errorCode, + Throwable cause) throws OperationFailedException + { + logger.error(message, cause); + throw new OperationFailedException(message, errorCode, cause); + } }