diff -r 000000000000 -r 1bce908db942 multimediacommsengine/mmcesrv/mmceserver/src/mcesip.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommsengine/mmcesrv/mmceserver/src/mcesip.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,1239 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mcesip.h" +#include "mcedefs.h" + + +const CSIPTransactionBase::TState KMceTrxStateUndefined = + static_cast(-1); + +// ----------------------------------------------------------------------------- +// MceSip::ResponseCode +// ----------------------------------------------------------------------------- +// +TUint MceSip::ResponseCode( CSIPClientTransaction& aResponse ) + { + return aResponse.ResponseElements()->StatusCode(); + } + +// ----------------------------------------------------------------------------- +// MceSip::ResponseType +// ----------------------------------------------------------------------------- +// +TMceSipResponseType MceSip::ResponseType( CSIPClientTransaction& aResponse ) + { + + TUint responseCode = ResponseCode( aResponse ); + + return ResponseType( responseCode ); + } + +// ----------------------------------------------------------------------------- +// MceSip::ResponseType +// ----------------------------------------------------------------------------- +// +TMceSipResponseType MceSip::ResponseType( TUint aCode ) + { + if ( aCode < KMceSipOK )//200 + { + return E1XX; + } + else if ( aCode < KMceSipMultipleChoices )//300 + { + return E2XX; + } + else if ( aCode < KMceSipBadRequest )//400 + { + return E3XX; + } + else if ( aCode < KMceSipServerInternalError )//500 + { + return E4XX; + } + else if ( aCode < KMceSipBusyEverywhere )//600 + { + return E5XX; + } + else + { + return E6XX; + } + } + +// ----------------------------------------------------------------------------- +// MceSip::ReasonPhraseL +// ----------------------------------------------------------------------------- +// +RStringF MceSip::ReasonPhraseL( TUint aStatusCode ) + { + RStringF phrase; + + switch( aStatusCode ) + { + case KMceSipOK: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseOk ); + break; + } + case KMceSipBadRequest: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseBadRequest ); + break; + } + case KMceSipUnauthorized: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseUnauthorized ); + break; + } + case KMceSipForbidden: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseForbidden ); + break; + } + case KMceSipNotFound: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseNotFound ); + break; + } + case KMceSipMethodNotAllowed: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseMethodNotAllowed ); + break; + } + case KMceSip4XXNotAcceptable: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseNotAcceptableHere ); + break; + } + case KMceSipProxyAuthenticationRequired: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseProxyAuthenticationRequired ); + break; + } + case KMceSipRequestTimeout: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseRequestTimeout ); + break; + } + case KMceSipUnsupportedMediaType: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseUnsupportedMediaType ); + break; + } + case KMceSipUnsupportedURIScheme: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseUnsupportedURIScheme ); + break; + } + case KMceSipBadExtension: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseBadExtension ); + break; + } + case KMceSipExtensionRequired: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseExtensionRequired ); + break; + } + case KMceSipSessionIntervalTooSmall: + case KMceSipIntervalTooBrief: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseIntervalTooBrief ); + break; + } + case KMceSipTemporarilyUnavailable: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseTemporarilyNotAvailable ); + break; + } + case KMceSipCallOrTransactionDoesNotExist: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseCallTransactionDoesNotExist ); + break; + } + case KMceSipLoopDetected: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseLoopDetected ); + break; + } + case KMceSipTooManyHops: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseTooManyHops ); + break; + } + case KMceSipBusyHere: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseBusyHere ); + break; + } + case KMceSipRequestTerminated: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseRequestTerminated ); + break; + } + case KMceSipNotAcceptableHere: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseNotAcceptableHere ); + break; + } + case KMceSipBadEvent: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseBadEvent ); + break; + } + case KMceSipRequestPending: + { + phrase = SIPStrings::Pool().OpenFStringL( KMceSipPhraseRequestPending() ); + break; + } + case KMceSipServerInternalError: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseServerInternalError ); + break; + } + case KMceSipNotImplemented: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseNotImplemented ); + break; + } + case KMceSipServiceUnavailable: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseServiceUnavailable ); + break; + } + case KMceSipVersionNotSupported: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseVersionNotSupported ); + break; + } + case KMceSipDecline: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseDecline ); + break; + } + case KMceSipServerTimeOut: + { + phrase = SIPStrings::StringF( SipStrConsts::EPhraseRequestTimeout ); + break; + } + + default: + { + phrase = SIPStrings::StringF( SipStrConsts::EEmpty ); + break; + } + } + + return phrase; + + } + + +// ----------------------------------------------------------------------------- +// MceSip::IsResponseTo +// ----------------------------------------------------------------------------- +// +TBool MceSip::IsResponseTo( CSIPClientTransaction& aResponse, RStringF aMethod ) + { + return &aResponse != NULL && aResponse.Type() == aMethod; + } + + +// ----------------------------------------------------------------------------- +// MceSip::TrxCompleted +// ----------------------------------------------------------------------------- +// +TBool MceSip::TrxCompleted( CSIPTransactionBase& aTransaction ) + { + // Invite transaction which is in confirmed state can be removed as well, + // as it means that error response has been already sent and SIP is + // just waiting for acks for certain time (T4). + CSIPTransactionBase::TState trxState = TrxState( aTransaction ); + return trxState == KMceTrxStateUndefined || + trxState == CSIPTransactionBase::ECompleted || + trxState == CSIPTransactionBase::ETerminated || + TrxType( aTransaction ) == SipStrConsts::EAck || + ( TrxType( aTransaction ) == SipStrConsts::EInvite && + trxState == CSIPTransactionBase::EConfirmed ); + } + + +// ----------------------------------------------------------------------------- +// MceSip::TrxState +// ----------------------------------------------------------------------------- +// +CSIPTransactionBase::TState MceSip::TrxState( + CSIPTransactionBase& aTransaction ) + { + CSIPTransactionBase::TState trxState = KMceTrxStateUndefined; + TRAP_IGNORE( ( trxState = aTransaction.StateL() ) ); + return trxState; + + } + +// ----------------------------------------------------------------------------- +// MceSip::TrxType +// ----------------------------------------------------------------------------- +// +TInt MceSip::TrxType( CSIPTransactionBase& aTransaction ) + { + return aTransaction.Type().Index( SIPStrings::Table() ); + } + + + + +// ----------------------------------------------------------------------------- +// MceSip::WarningPhraseL +// ----------------------------------------------------------------------------- +// +RStringF MceSip::WarningPhraseL( TUint aWarnCode ) + { + + RStringF warningPhrase; + + + switch( aWarnCode ) + { + case KMceSipWarnIncompatibleNetworkProtocol: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase300() ); + break; + } + case KMceSipWarnIncompatibleNetworkAddressFormat: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase301() ); + break; + } + case KMceSipWarnIncompatibleTransportProtocol: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase302() ); + break; + } + case KMceSipWarnIncompatibleBandwidthUnits: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase303() ); + break; + } + case KMceSipWarnMediaTypeNotAvailable: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase304() ); + break; + } + case KMceSipWarnIncompatibleMediaFormat: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase305() ); + break; + } + case KMceSipWarnAttributeNotUnderstood: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase306() ); + break; + } + case KMceSipWarnSessionDescriptionParameterNotUnderstood: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase307() ); + break; + } + case KMceSipWarnMulticastNotAvailable: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase330() ); + break; + } + case KMceSipWarnUnicastNotAvailable: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase331() ); + break; + } + case KMceSipWarnInsufficientBandwidth: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase370() ); + break; + } + case KMceSipWarnMiscellaneous: + { + warningPhrase = + SIPStrings::Pool().OpenFStringL( KMceSipWarnPhrase399() ); + break; + } + default: + { + warningPhrase = SIPStrings::StringF( SipStrConsts::EEmpty ); + break; + } + } + return warningPhrase; + } + + + +// ----------------------------------------------------------------------------- +// MceSip::IsSIPStackError +// ----------------------------------------------------------------------------- +// +TBool MceSip::IsSIPStackError( TInt aError ) + { + return IsSDPError( aError ) || + ( aError >= KErrSIPInvalidURIType + && aError <= KErrSIPMalformedMessage ); + + } + +// ----------------------------------------------------------------------------- +// MceSip::IsSDPError +// ----------------------------------------------------------------------------- +// +TBool MceSip::IsSDPError( TInt aError ) + { + return aError >= KErrSdpCodecDecode && aError <= KErrSdpCodecVersionField; + + } + +// ----------------------------------------------------------------------------- +// MceSip::ErrorResponse +// ----------------------------------------------------------------------------- +// +void MceSip::ErrorResponse( TInt aError, + TUint& aSIPResponseCode, + TInt& aReasonPhrase ) + { + + if ( IsSDPError( aError ) ) + { + aSIPResponseCode = KMceSipBadRequest; + aReasonPhrase = SipStrConsts::EPhraseBadRequest; + } + else + { + aSIPResponseCode = KMceSipServerInternalError; + aReasonPhrase = SipStrConsts::EPhraseServerInternalError; + } + + } + + +// ----------------------------------------------------------------------------- +// MceSip::DiscardRequest +// ----------------------------------------------------------------------------- +// +TInt MceSip::DiscardRequest( CSIPServerTransaction& aRequest, TInt aError, + TBool aRetryIndication ) + { + TInt status = KErrNone; + TRAP( status, DoDiscardRequestL( aRequest, aError, aRetryIndication ) ); + return status; + } + +// ----------------------------------------------------------------------------- +// MceSip::DiscardRequest +// ----------------------------------------------------------------------------- +// +TInt MceSip::DiscardRequest( CSIPServerTransaction* aRequest, TInt aError, + TBool aRetryIndication ) + { + TInt status = DiscardRequest( *aRequest, aError, aRetryIndication ); + delete aRequest; + + return status; + + } + + +// ----------------------------------------------------------------------------- +// MceSip::Method +// ----------------------------------------------------------------------------- +// +RStringF MceSip::Method( CSIPServerTransaction& aRequest ) + { + const CSIPRequestElements* request = aRequest.RequestElements(); + if ( request ) + { + return request->Method(); + } + else + { + return SIPStrings::StringF( SipStrConsts::EEmpty ); + } + + } + +// ----------------------------------------------------------------------------- +// MceSip::AddressToTextL +// ----------------------------------------------------------------------------- +// +HBufC8* MceSip::AddressToTextL( const CSIPAddress& aToAddr ) + { + HBufC8* address = aToAddr.ToTextLC(); + CleanupStack::Pop( address ); + return address; + } + +// ----------------------------------------------------------------------------- +// MceSip::ToFromHeaderL +// ----------------------------------------------------------------------------- +// +CSIPFromHeader* MceSip::ToFromHeaderL( const TDesC8& aAddress ) + { + + CSIPAddress* sipAddressFrom = CSIPAddress::DecodeL( aAddress ); + CleanupStack::PushL( sipAddressFrom ); + CSIPFromHeader* fromHeader = CSIPFromHeader::NewL( sipAddressFrom ); + CleanupStack::Pop( sipAddressFrom ); + return fromHeader; + + } + + +// ----------------------------------------------------------------------------- +// MceSip::ToContentTypeHeaderL +// ----------------------------------------------------------------------------- +// +CSIPContentTypeHeader* + MceSip::ToContentTypeHeaderL( TMceContentType aContentType, + const HBufC8* aUserDefinedContentType ) + { + + CSIPContentTypeHeader* contentTypeHeader = NULL; + + if ( aUserDefinedContentType ) + { + contentTypeHeader = + CSIPContentTypeHeader::DecodeL( *aUserDefinedContentType ); + + } + else if ( aContentType == EMceContentTypeSDP ) + { + contentTypeHeader = + CSIPContentTypeHeader::NewL( KMceSipMediaTypeApplication, + KMceSipMediaSubTypeSDP ); + + } + else if ( aContentType == EMceContentTypeMultiPart ) + { + contentTypeHeader = + CSIPContentTypeHeader::NewLC( KMceSipMPartMediaTypeMultipart, + KMceSipMPartMediaSubTypeMixed ); + + RStringF paramKey = SIPStrings::Pool().OpenFStringL( KMceSipMPartBoundary ); + CleanupClosePushL( paramKey ); + RStringF paramValue = SIPStrings::Pool().OpenFStringL( KMceSipMPartMessageBoundary ); + CleanupClosePushL( paramValue ); + + contentTypeHeader->SetParamL( paramKey, paramValue ); + CleanupStack::PopAndDestroy(); // paramValue + CleanupStack::PopAndDestroy(); // paramKey + CleanupStack::Pop( contentTypeHeader ); + + } + else + { + //NOP + } + + return contentTypeHeader; + + } + + +// ----------------------------------------------------------------------------- +// MceSip::ToSIPExtensionHeadersL +// ----------------------------------------------------------------------------- +// +void MceSip::ToSIPExtensionHeadersL( RPointerArray& aSIPHeaders, + const MDesC8Array& aHeaders ) + { + + for ( int i = 0; i < aHeaders.MdcaCount(); i++ ) + { + TPtrC8 param = aHeaders.MdcaPoint( i ); + TInt index = param.Locate( KMceSipSeparator ); + if ( index != KErrNotFound && + param.Left( index ) != KMceSipSubscriptionStateHeader ) + { + CSIPExtensionHeader* extHeader = CSIPExtensionHeader::NewL( + param.Left(index), + param.Right( param.Length() - ( index + 1 ) ) ); + CleanupStack::PushL( extHeader ); + User::LeaveIfError( aSIPHeaders.Append( extHeader ) ); + CleanupStack::Pop( extHeader ); + } + } + } + +// ----------------------------------------------------------------------------- +// MceSip::UserHeadersToTextArrayL +// ----------------------------------------------------------------------------- +// +CDesC8Array* MceSip::UserHeadersToTextArrayL( + CSIPTransactionBase& aTransaction, + const CSIPDialog& aDialog ) + { + CDesC8ArrayFlat* headers = new (ELeave) CDesC8ArrayFlat( KMceArrayGranularity ); + CleanupStack::PushL( headers ); + + HBufC8* head = NULL; + const CSIPHeaderBase* callid = NULL; + const CSIPHeaderBase* cseq = NULL; + const CSIPFromHeader* from = NULL; + const CSIPToHeader* to = NULL; + const CSIPMessageElements* elements = ToMessageElements( aTransaction ); + + if ( aTransaction.IsSIPClientTransaction() ) + { + const CSIPResponseElements* responseElements = + static_cast( aTransaction ). + ResponseElements(); + cseq = responseElements ? responseElements->CSeqHeader() : NULL; + + from = responseElements ? responseElements->FromHeader() : NULL; + to = responseElements ? responseElements->ToHeader() : NULL; + + } + else + { + + const CSIPRequestElements* requestElements = + static_cast( aTransaction ). + RequestElements(); + from = requestElements ? requestElements->FromHeader() : NULL; + to = requestElements ? requestElements->ToHeader() : NULL; + + } + + from = !from ? &aDialog.FromHeader() : from; + to = !to ? &aDialog.ToHeader() : to; + + head = from->ToTextLC(); + headers->AppendL( *head ); + CleanupStack::PopAndDestroy( head ); + head = to->ToTextLC(); + headers->AppendL( *head ); + CleanupStack::PopAndDestroy( head ); + + if ( cseq ) + { + head = cseq->ToTextLC(); + headers->AppendL( *head ); + CleanupStack::PopAndDestroy( head ); + } + + TRAPD( error, callid = &aDialog.CallIdL() ); + if ( error == KErrNone ) + { + head = callid->ToTextLC(); + headers->AppendL( *head ); + CleanupStack::PopAndDestroy( head ); + } + + + if ( elements ) + { + const RPointerArray& sipHeaders = + elements->UserHeaders(); + + for ( TInt i=0; i < sipHeaders.Count(); i++ ) + { + CSIPHeaderBase* anotherhead = sipHeaders[ i ]; + head = anotherhead->ToTextLC(); + headers->AppendL( *head ); + CleanupStack::PopAndDestroy( head ); + } + + + } + + CleanupStack::Pop( headers ); + return headers; + + } + +// ----------------------------------------------------------------------------- +// MceSip::ToContactHeaderL +// ----------------------------------------------------------------------------- +// +CSIPContactHeader* MceSip::ToContactHeaderL( const TDesC8& aContact ) + { + CSIPContactHeader* contact = NULL; + + RPointerArray< CSIPContactHeader > contacts = CSIPContactHeader::DecodeL( aContact ); + if ( contacts.Count() > 0 ) + { + contact = contacts[0]; + contacts.Remove(0); + contacts.ResetAndDestroy(); + } + else + { + contacts.Close(); + User::Leave( KErrNotFound ); + } + + return contact; + + } + + +// ----------------------------------------------------------------------------- +// MceSip::HasSipsUriInContact +// ----------------------------------------------------------------------------- +// +TBool MceSip::HasSipsUriInContactL( const CSIPMessageElements& aMessage ) + { + TBool hasSipsUri = EFalse; + CSIPHeaderBase* contact = FindHeader( aMessage, SIPStrings::StringF( + SipStrConsts::EContactHeader ) ); + + if ( !contact ) + { + contact = FindHeader( aMessage, SIPStrings::StringF( + SipStrConsts::EContactHeaderCompact ) ); + } + + if ( contact ) + { + const TDesC8& uriScheme = static_cast< CSIPContactHeader* >( contact )-> + SIPAddress()->Uri8().Uri().Extract( EUriScheme ); + if ( uriScheme.FindF( KMceSipUriSchemeSIPs ) != KErrNotFound ) + { + hasSipsUri = ETrue; + } + } + + return hasSipsUri; + } + +// ----------------------------------------------------------------------------- +// MceSip::HasTlsInContact +// ----------------------------------------------------------------------------- +// +TBool MceSip::HasTlsInContactL( const CSIPMessageElements& aMessage ) + { + TBool hasTls = EFalse; + CSIPHeaderBase* contact = FindHeader( aMessage, SIPStrings::StringF( + SipStrConsts::EContactHeader ) ); + + if ( !contact ) + { + contact = FindHeader( aMessage, SIPStrings::StringF( + SipStrConsts::EContactHeaderCompact ) ); + } + + if ( contact ) + { + + const TDesC8& uriPath = static_cast< CSIPContactHeader* >( contact )->SIPAddress()->Uri8().Uri().Extract( EUriPath ); + if ( uriPath.FindF( KMceSipTransportTLS ) != KErrNotFound ) + { + hasTls = ETrue; + } + } + + return hasTls; + } +// ----------------------------------------------------------------------------- +// MceSip::AddSupportedHeaderL +// ----------------------------------------------------------------------------- +// +void MceSip::AddSupportedHeaderL( RPointerArray& aSIPHeaders, + const TDesC8& aExtension ) + { + RStringF tag = SIPStrings::Pool().OpenFStringL( aExtension ); + CleanupClosePushL( tag ); + CSIPSupportedHeader* header = CSIPSupportedHeader::NewL( tag ); + CleanupStack::PopAndDestroy(); // tag + CleanupStack::PushL( header ); + aSIPHeaders.AppendL( header ); + CleanupStack::Pop( header ); + } + +// ----------------------------------------------------------------------------- +// MceSip::AddRequireHeaderL +// ----------------------------------------------------------------------------- +// +void MceSip::AddRequireHeaderL( RPointerArray& aSIPHeaders, + const TDesC8& aExtension ) + { + RStringF tag = SIPStrings::Pool().OpenFStringL( aExtension ); + CleanupClosePushL( tag ); + CSIPRequireHeader* header = CSIPRequireHeader::NewL( tag ); + CleanupStack::PopAndDestroy(); // tag + CleanupStack::PushL( header ); + aSIPHeaders.AppendL( header ); + CleanupStack::Pop( header ); + } + +// ----------------------------------------------------------------------------- +// MceSip::AddAllowHeaderL +// ----------------------------------------------------------------------------- +// +void MceSip::AddAllowHeaderL( RPointerArray& aSIPHeaders, + TInt aMethod ) + { + RStringF method = SIPStrings::StringF( aMethod ); + CSIPAllowHeader* header = CSIPAllowHeader::NewL( method ); + CleanupStack::PushL( header ); + aSIPHeaders.AppendL( header ); + CleanupStack::Pop( header ); + } + +// ----------------------------------------------------------------------------- +// MceSip::AddRAckHeaderL +// ----------------------------------------------------------------------------- +// +void MceSip::AddRAckHeaderL( RPointerArray& aSIPHeaders, + const CSIPResponseElements& aResponse ) + { + TInt rseq = RSeq( aResponse ); + + if (rseq == KErrNotFound ) + { + User::Leave( KErrArgument ); + } + + const CSIPCSeqHeader* cseqHeader = aResponse.CSeqHeader(); + __ASSERT_ALWAYS( MCE_NOT_NULL_PTR( cseqHeader ), User::Leave( KErrArgument ) ); + + CSIPRAckHeader* header = CSIPRAckHeader::NewL( rseq, + cseqHeader->Seq(), + cseqHeader->Method() ); + CleanupStack::PushL( header ); + aSIPHeaders.AppendL( header ); + CleanupStack::Pop( header ); + } + + +// ----------------------------------------------------------------------------- +// MceSip::ToMessageElements +// ----------------------------------------------------------------------------- +// +const CSIPMessageElements* MceSip::ToMessageElements( + CSIPTransactionBase& aTransaction ) + { + + const CSIPMessageElements* elements = NULL; + + if ( aTransaction.IsSIPClientTransaction() ) + { + CSIPClientTransaction& trx = + static_cast( aTransaction ); + const CSIPResponseElements* resElements = trx.ResponseElements(); + + elements = resElements ? &resElements->MessageElements() : NULL; + + } + else + { + CSIPServerTransaction& trx = + static_cast( aTransaction ); + const CSIPRequestElements* reqElements = trx.RequestElements(); + + elements = reqElements ? &reqElements->MessageElements() : NULL; + } + + return elements; + + } + +// ----------------------------------------------------------------------------- +// MceSip::HasContent +// ----------------------------------------------------------------------------- +// +TBool MceSip::HasContent( CSIPTransactionBase& aTransaction ) + { + const CSIPMessageElements* elements = ToMessageElements( aTransaction ); + if (elements) + return elements->Content().Length() > 0; + else return EFalse; + } +/* +TBool MceSip::HasContent( CSIPTransactionBase& aTransaction ) + { + TBool hasContent = EFalse; + const CSIPMessageElements* elements = ToMessageElements( aTransaction ); + if ( elements && elements->Content().Length() > 0 ) + { + hasContent = ETrue; + } + return hasContent; + }*/ + +// ----------------------------------------------------------------------------- +// MceSip::SIPStringIndex +// ----------------------------------------------------------------------------- +// +TInt MceSip::SIPStringIndex( const TDesC8& aSIPString ) + { + TInt searchInd = KErrNotFound; + const TStringTable& strTable = SIPStrings::Table(); + + TUint strInd = 0;// index in table + + while ( searchInd == KErrNotFound && strInd < strTable.iCount ) + { + if ( SIPStrings::StringF( strInd ).DesC().CompareF( aSIPString ) == 0 ) + { + searchInd = strInd; + } + else + { + strInd++; + } + } + return searchInd; + } + +// ----------------------------------------------------------------------------- +// MceSip::DoDiscardRequestL +// ----------------------------------------------------------------------------- +// +void MceSip::DoDiscardRequestL( CSIPServerTransaction& aRequest, TInt aError, + TBool aRetryIndication ) + { + CSIPResponseElements* response = NULL; + TUint responseCode = 0; + + if ( aError >= (TInt)KMceSipTrying ) + { + responseCode = (TUint)aError; + RStringF reasonPhrase = ReasonPhraseL( responseCode ); + CleanupClosePushL( reasonPhrase ); + response = + CSIPResponseElements::NewL( responseCode, reasonPhrase ); + + CleanupStack::PopAndDestroy();//reasonPhrase + } + else + { + TInt reasonPhrase = 0; + + ErrorResponse( aError, responseCode, reasonPhrase ); + + response = + CSIPResponseElements::NewL( responseCode, + SIPStrings::StringF( reasonPhrase ) ); + } + + CleanupStack::PushL( response ); + + if ( aRetryIndication ) + { + + CSIPMessageElements& elements = response->MessageElements(); + + //create Retry-After header + RPointerArray headers; + CSIPHeaderBase::PushLC( &headers ); + + CSIPRetryAfterHeader* retryAfter = + CSIPRetryAfterHeader::NewLC( Random( KMceRandMinRetryValue, + KMceRandMaxRetryValue ) ); + headers.AppendL( retryAfter ); + CleanupStack::Pop( retryAfter ); + //send invitation + elements.SetUserHeadersL( headers ); + CleanupStack::Pop( &headers ); + + } + + aRequest.SendResponseL( response ); + CleanupStack::Pop( response ); + + + } + +// ----------------------------------------------------------------------------- +// MceSip::FindHeader +// ----------------------------------------------------------------------------- +// +CSIPHeaderBase* MceSip::FindHeader( const CSIPMessageElements& aMessage, + RStringF aHeaderName ) + { + TBool found = EFalse; + CSIPHeaderBase* header = NULL; + const RPointerArray& headers = aMessage.UserHeaders(); + + for ( TInt i=0; i < headers.Count() && !found; i++ ) + { + header = headers[i]; + if ( header->Name() == aHeaderName ) + { + found = ETrue; + } + else + { + header = NULL; + } + } + return header; + } + +// ----------------------------------------------------------------------------- +// MceSip::FindHeader +// ----------------------------------------------------------------------------- +// +CSIPHeaderBase* MceSip::FindHeader( const RPointerArray& aHeaders , + RStringF aHeaderName ) + { + TBool found = EFalse; + CSIPHeaderBase* header = NULL; + + for ( TInt i=0; i < aHeaders.Count() && !found; i++ ) + { + header = aHeaders[i]; + if ( header->Name() == aHeaderName ) + { + found = ETrue; + } + else + { + header = NULL; + } + } + return header; + } +// ----------------------------------------------------------------------------- +// MceSip::FindHeadersL +// ----------------------------------------------------------------------------- +// +void MceSip::FindHeadersL( const CSIPMessageElements& aMessage, + RStringF aHeaderName, + RPointerArray& aHeaders ) + { + const RPointerArray& headers = aMessage.UserHeaders(); + CSIPHeaderBase* header = NULL; + + for ( TInt i=0; i < headers.Count(); i++ ) + { + header = headers[i]; + if ( header->Name() == aHeaderName ) + { + aHeaders.AppendL( header ); + } + } + } + +// ----------------------------------------------------------------------------- +// MceSip::CompareUri +// ----------------------------------------------------------------------------- +// +TInt MceSip::CompareUri( const CUri8& aRemoteUriOne, const CUri8& aRemoteUriTwo ) + { + TInt ret = KErrGeneral; + + if ( aRemoteUriOne.Uri().Compare( aRemoteUriTwo.Uri(), EUriScheme ) == KErrNone && + aRemoteUriOne.Uri().Compare( aRemoteUriTwo.Uri(), EUriUserinfo ) == KErrNone && + aRemoteUriOne.Uri().Compare( aRemoteUriTwo.Uri(), EUriHost ) == KErrNone ) + { + ret = KErrNone; + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// MceSip::HasHeaderValueL +// ----------------------------------------------------------------------------- +// +TBool MceSip::HasHeaderValueL( const CSIPMessageElements& aMessage, + TInt aHeaderName, + const TDesC8& aHeaderValue ) + { + TBool found = EFalse; + CSIPHeaderBase* header = NULL; + const RPointerArray& headers = aMessage.UserHeaders(); + + for ( TInt i=0; i < headers.Count() && !found; i++ ) + { + header = headers[i]; + if ( header->Name() == SIPStrings::StringF( aHeaderName ) ) + { + HBufC8* value = header->ToTextValueL(); + if ( value->CompareF( aHeaderValue ) == 0 ) + { + found = ETrue; + } + delete value; + } + + if ( !found ) + { + header = NULL; + } + } + return found; + } + +// ----------------------------------------------------------------------------- +// MceSip::HasHeaderValueL +// ----------------------------------------------------------------------------- +// +TBool MceSip::HasHeaderValueL( const RPointerArray& aHeaders, + TInt aHeaderName, + const TDesC8& aHeaderValue ) + { + TBool found = EFalse; + CSIPHeaderBase* header = NULL; + + for ( TInt i=0; i < aHeaders.Count() && !found; i++ ) + { + header = aHeaders[i]; + if ( header->Name() == SIPStrings::StringF( aHeaderName ) ) + { + HBufC8* value = header->ToTextValueL(); + if ( value->CompareF( aHeaderValue ) == 0 ) + { + found = ETrue; + } + delete value; + } + + if ( !found ) + { + header = NULL; + } + } + return found; + } +// MceSip::Random +// ----------------------------------------------------------------------------- +// +TUint MceSip::Random( TUint aMinValue, TUint aMaxValue ) + { + TUint randomValue( aMinValue <= aMaxValue ? aMinValue : 0 ); + + if ( aMinValue <= aMaxValue ) + { + + TTime time; + time.HomeTime(); + TInt64 seed( time.Int64() ); + + + for ( TUint i = 0; i < ( aMaxValue - aMinValue ); i++ ) + { + TInt random = Math::Rand( seed ); + TReal random2 = ( TReal )random / KMceRandDividerOne; + TUint random3 = ( TUint )( aMaxValue * random2 ) / + KMceRandDividerTwo; + + if ( aMinValue <= random3 && aMaxValue >= random3 ) + { + randomValue = random3; + break; + } + } + } + + return randomValue; + + } + + +// ----------------------------------------------------------------------------- +// MceSip::HeaderValueL +// ----------------------------------------------------------------------------- +// +TUint MceSip::HeaderValueL( TPtr8 aHeader ) + { + TUint value; + aHeader.Trim(); + + TInt index = aHeader.Locate( KMceSipHeaderSeparator ); + if( index != KErrNotFound ) + { + TLex8 lexValue( aHeader.Left( index ) ); + User::LeaveIfError ( lexValue.Val( value, EDecimal ) ); + } + else + { + TLex8 lexValue( aHeader ); + User::LeaveIfError ( lexValue.Val( value, EDecimal ) ); + } + + return value; + + } + + + +// ----------------------------------------------------------------------------- +// MceSip::RSeq +// ----------------------------------------------------------------------------- +// + +TInt MceSip::RSeq( const CSIPResponseElements& aResponseElements ) + { + + TInt value = KErrNotFound; // if its not found + + CSIPHeaderBase* rseqHeader = FindHeader( aResponseElements.MessageElements(), + SIPStrings::StringF( SipStrConsts::ERSeqHeader ) ); + + if ( rseqHeader ) + { + value = static_cast< CSIPRSeqHeader* >( rseqHeader )->Value(); + } + + return value; + } + + // ----------------------------------------------------------------------------- +// MceSip::BasicAllowMethods +// ----------------------------------------------------------------------------- +// +void MceSip::BasicAllowMethodsL( RArray& aArray ) + { + User::LeaveIfError( aArray.Append( SipStrConsts::EInvite )); + User::LeaveIfError( aArray.Append( SipStrConsts::EAck )); + User::LeaveIfError( aArray.Append( SipStrConsts::ECancel )); + User::LeaveIfError( aArray.Append( SipStrConsts::EOptions )); + User::LeaveIfError( aArray.Append( SipStrConsts::EBye )); + } + + +// End of File