diff -r 000000000000 -r f0cf47e981f9 mmsharing/mmshavailability/src/musavacapabilityquerybase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmsharing/mmshavailability/src/musavacapabilityquerybase.cpp Thu Dec 17 08:44:37 2009 +0200 @@ -0,0 +1,571 @@ +/* +* Copyright (c) 2005-2007 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: Sent capability query (OPTIONS) +* +*/ + + +#include "musavacapabilityquerybase.h" +#include "muscleanupresetanddestroy.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mussettings.h" +#include "muslogger.h" +#include "mmusavacapabilityqueryobserver.h" +#include "musavacapability.h" +#include "musavacapabilityexchange.h" +#include "musavaterminal.h" +#include "musavacapabilitycontext.h" +#include "musavasipheaderutil.h" +#include "mussesseioninformationapi.h" + +// -------------------------------------------------------------------------- +// C++ constructor +// -------------------------------------------------------------------------- +// +CMusAvaCapabilityQueryBase::CMusAvaCapabilityQueryBase( + CMusAvaCapability& aCapability, + CSIPConnection& aSIPConnection, + CSIPProfile& aProfile ) + : iCapability( aCapability ), + iSIPConnection( aSIPConnection ), + iProfile( aProfile ), + iState( ECapabilityQueryCreated ), + iResult( KCapabilityQueryNotReady ) + { + } + +// -------------------------------------------------------------------------- +// C++ destructor +// -------------------------------------------------------------------------- +// +CMusAvaCapabilityQueryBase::~CMusAvaCapabilityQueryBase() + { + MUS_LOG( + "mus: [MUSAVA] -> CMusAvaCapabilityQueryBase::~CMusAvaCapabilityQueryBase" ) + + delete iRegisteredContact; + delete iOriginator; + if ( iTerminal ) + { + iTerminal->DetachQuery( *this ); + } + ResetAndDestroyTrx(); + MUS_LOG( "mus: [MUSAVA] -> StringPools are getting closed." ) + MUS_LOG( + "mus: [MUSAVA] <- CMusAvaCapabilityQueryBase::~CMusAvaCapabilityQueryBase" ) + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::ConstructL +// -------------------------------------------------------------------------- +// +void CMusAvaCapabilityQueryBase::ConstructL( const TDesC& aSipAddress ) + { + MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapabilityQueryBase::ConstructL" ) + + // If string pool is opened already , then dont care. + + User::LeaveIfError( aSipAddress.Length() > 0 ? KErrNone : KErrArgument ); + + // If it is not registered , just leave. + TBool isRegistered = ETrue; + iProfile.GetParameter( KSIPProfileRegistered, isRegistered ); + User::LeaveIfError( isRegistered ? KErrNone : KErrArgument ); + + TInt err( KErrNotFound ); + const TDesC8* registeredContact( NULL ); + err = iProfile.GetParameter( KSIPRegisteredContact, registeredContact ); + if( err ) + { + MUS_LOG1( "mus: [MUSAVA] iProfile.GetParameter Contact -> %d", err ) + User::LeaveIfError( err ); + } + + // contactHeader array will only contain one instance of CSIPContactHeader, + // since only one registered contact is decoded + RPointerArray contactHeader = + CSIPContactHeader::DecodeL( *registeredContact ); + MusCleanupResetAndDestroyPushL( contactHeader ); + + // leave if there is at least one contact not present + if ( contactHeader.Count() < 1 ) + { + MUS_LOG1( "mus: [MUSAVA] contactHeader has %d instances, instead of 1", + contactHeader.Count() ); + User::Leave( KErrNotFound ); + } + + // if more contact than pick the first one. Sip assures in idle case + // it should always return only one registered contact. + CSIPAddress* sipAddress = contactHeader[0]->SIPAddress(); + if ( !sipAddress ) + { + MUS_LOG( "mus: [MUSAVA] name-address not present") + User::Leave( KErrNotFound ); + } + iRegisteredContact = CUri8::NewL( sipAddress->Uri8().Uri() ); + MUS_LOG_TDESC8( " mus: [MUSAVA] iRegisteredContact : ", (iRegisteredContact->Uri().UriDes())); + CleanupStack::PopAndDestroy( &contactHeader ); + + sipAddress = NULL; + const MDesC8Array* aors = NULL; + User::LeaveIfError(iProfile.GetParameter( KSIPRegisteredAors, aors )); + MUS_LOG( "mus: [MUSAVA] iProfile.GetParameter -> OK " ) + if( !aors || aors->MdcaCount() <= 0 ) User::Leave(KErrArgument); + MUS_LOG_TDESC8( " mus: [MUSAVA] AOR -> 0 : ", aors->MdcaPoint(0)); + sipAddress = CSIPAddress::DecodeL( aors->MdcaPoint(0) ); + MUS_LOG( "mus: [MUSAVA] CSIPAddress::DecodeL -> OK " ) + CleanupStack::PushL( sipAddress ); + iOriginator = CUri8::NewL(sipAddress->Uri8().Uri()); + MUS_LOG_TDESC8( " mus: [MUSAVA] iOriginator : ", (iOriginator->Uri().UriDes())); + CleanupStack::PopAndDestroy(sipAddress); + + HBufC8* sipAddress8 = EscapeUtils::ConvertFromUnicodeToUtf8L( aSipAddress ); + CleanupStack::PushL( sipAddress8 ); + iTerminal = &Capability().Exchange().TerminalL( sipAddress8->Des() ); + CleanupStack::PopAndDestroy( sipAddress8 ) ; + iTerminal->AttachQuery( *this ); + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQueryBase::ConstructL" ) + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::Capability +// -------------------------------------------------------------------------- +// +const CMusAvaCapability& CMusAvaCapabilityQueryBase::Capability() const + { + return iCapability; + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::SetState +// -------------------------------------------------------------------------- +// +void CMusAvaCapabilityQueryBase::SetState( + CMusAvaCapabilityQueryBase::TState aState ) + { + iState = aState; + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::SetResult +// -------------------------------------------------------------------------- +// +void CMusAvaCapabilityQueryBase::SetResult( TInt aResult ) + { + iResult = aResult; + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::Terminal +// -------------------------------------------------------------------------- +// +CMusAvaTerminal& CMusAvaCapabilityQueryBase::Terminal() + { + return *iTerminal; + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::ExecuteL +// -------------------------------------------------------------------------- +// +void CMusAvaCapabilityQueryBase::ExecuteL() + { + MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapabilityQueryBase::ExecuteL" ) + + __ASSERT_ALWAYS( + State() != ECapabilityQueryPrepared, User::Leave( KErrGeneral ) ); + + if ( State() == ECapabilityQueryCreated ) + { + RPointerArray headers; + CSIPHeaderBase::PushLC( &headers ); + + Prepare( headers ); + + if ( State() == ECapabilityQueryPrepared ) + { + CMusAvaSipheaderUtil::AddAcceptContactHeaderL( headers, + Capability().Feature() ); + MUS_LOG( "mus: [MUSAVA] AddAcceptContactHeaderL -> Success ") + CMusAvaSipheaderUtil::AddAcceptEncodingHeaderL(headers); + MUS_LOG( "mus: [MUSAVA] AddAcceptEncodingHeaderL -> Success ") + CMusAvaSipheaderUtil::AddAcceptLanguageHeaderL(headers); + MUS_LOG( "mus: [MUSAVA] AddAcceptLanguageHeaderL -> Success ") + CMusAvaSipheaderUtil::AddAcceptSdpHeaderL(headers); + MUS_LOG( "mus: [MUSAVA] AddAcceptSDPHeaderL -> Success ") + CMusAvaSipheaderUtil::AddPreferredIdentityHeaderL(headers, + iOriginator->Uri().UriDes()); + MUS_LOG( "mus: [MUSAVA] AddPreferredIdentityHeaderL -> Success ") + AddContactHeaderL( headers ); + MUS_LOG( "mus: [MUSAVA] AddContactHeaderL -> Success ") + + TBool usePrivacy = MultimediaSharingSettings::PrivacySetting(); + if ( usePrivacy ) + { + NMusSessionInformationApi::TMusClirSetting clir = + NMusSessionInformationApi::ESendOwnNumber; + RProperty::Get( NMusSessionInformationApi::KCategoryUid, + NMusSessionInformationApi::KMusClirSetting, + reinterpret_cast( clir ) ); + usePrivacy = ( clir == NMusSessionInformationApi::EDoNotSendOwnNumber ); + } + + if (usePrivacy) + { + CMusAvaSipheaderUtil::AddPrivacyHeaderL( headers ); + MUS_LOG( "mus: [MUSAVA] AddPrivacyHeaderL -> Success ") + } + //terminal ID + if ( Capability().Exchange().TerminalId().Length() > 0 ) + { + MUS_LOG( "mus: [MUSAVA] Adding User-Agent header" ) + CSIPHeaderBase* userAgent = + MusAvaCapabilityContext::UserAgentHeaderLC( + Capability().Exchange().TerminalId() ); + headers.AppendL( userAgent ); + CleanupStack::Pop( userAgent ); + } + + //remote uri ( will be used as ToHeader ) + CUri8* remoteUri = + MusAvaCapabilityContext::ToUriL( Terminal().Uri() ); + CleanupStack::PushL( remoteUri ); + CSIPRequestElements* request = + CSIPRequestElements::NewL( remoteUri ); + CleanupStack::Pop( remoteUri ); + CleanupStack::PushL( request ); + + if (usePrivacy) + { + _LIT8( KAnonymous, + "\"Anonymous\" " ); + CSIPFromHeader* from = CSIPFromHeader::DecodeL( KAnonymous ); + CleanupStack::PushL( from ); + request->SetFromHeaderL( from ); + CleanupStack::Pop( from ); + } + + request->SetMethodL( + SIPStrings::StringF( SipStrConsts::EOptions ) ); + + CSIPMessageElements& message = request->MessageElements(); + message.SetUserHeadersL( headers ); + + HBufC8* content = ContentLC(); + CMusAvaSipheaderUtil::AddSdpL(request,content); + CleanupStack::Pop(content) ; + + ResetAndDestroyTrx(); + + MUS_LOG( "mus: [MUSAVA] Sending OPTIONS request ...." ) + iTrx = iSIPConnection.SendRequestL( request, iProfile ); + CleanupStack::Pop( request ); + + iState = ECapabilityQueryExecuting; + MUS_LOG( "mus: [MUSAVA] OPTIONS request sent" ) + } + + CleanupStack::PopAndDestroy( &headers ); + } + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQueryBase::ExecuteL" ) + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::CompletedL +// -------------------------------------------------------------------------- +// +void CMusAvaCapabilityQueryBase::CompletedL( + const CSIPClientTransaction& aResponse ) + { + MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapabilityQueryBase::CompletedL" ) + + if ( iTrx && *iTrx == aResponse ) + { + TUint statusCode = aResponse.ResponseElements()->StatusCode(); + if ( 100 <= statusCode && statusCode < 200 ) + { + return; + } + DoCompletedL( aResponse ); + if ( State() == ECapabilityQueryCompleted ) + { + MUS_LOG( "mus: [MUSAVA] query completed" ) + Capability().Exchange().QueryObserver().CapabilitiesResolved( + *this ); + } + } + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQueryBase::CompletedL" ) + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::Canceled +// -------------------------------------------------------------------------- +// +void CMusAvaCapabilityQueryBase::Canceled( + const CSIPClientTransaction& aTransaction ) + { + MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapabilityQueryBase::Canceled" ) + if ( iTrx && *iTrx == aTransaction ) + { + MUS_LOG( "mus: [MUSAVA] query canceled" ) + + SetState( ECapabilityQueryCompleted ); + SetResult( KCapabilityCapabilitesNotFound ); + Capability().Exchange().QueryObserver().CapabilitiesResolved( + *this ); + } + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQueryBase::Canceled" ) + } + + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::AddContactHeaderL +// -------------------------------------------------------------------------- +// +void CMusAvaCapabilityQueryBase::AddContactHeaderL( + RPointerArray& aRequestHeaders ) + { + + MUS_LOG( + "mus: [MUSAVA] -> CMusAvaCapabilityQueryBase::AddContactHeaderL" ) + CSIPContactHeader* contact = + MusAvaCapabilityContext::ContactHeaderLC( *iRegisteredContact, + Capability().Feature() ); + aRequestHeaders.AppendL( contact ); + CleanupStack::Pop( contact ); + MUS_LOG( + "mus: [MUSAVA] <- CMusAvaCapabilityQueryBase::AddContactHeaderL" ) + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::State +// -------------------------------------------------------------------------- +// +CMusAvaCapabilityQueryBase::TState CMusAvaCapabilityQueryBase::State() const + { + return iState; + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::Result +// -------------------------------------------------------------------------- +// +TInt CMusAvaCapabilityQueryBase::Result() const + { + return iResult; + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::ResetAndDestroyTrx +// -------------------------------------------------------------------------- +// +void CMusAvaCapabilityQueryBase::ResetAndDestroyTrx() + { + delete iTrx; + iTrx = NULL; + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::LocalAddress +// -------------------------------------------------------------------------- +// +const CUri8& CMusAvaCapabilityQueryBase::LocalAddress() const + { + return *iOriginator; + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::ResponseContentLC +// -------------------------------------------------------------------------- +// +HBufC8* CMusAvaCapabilityQueryBase::ContentLC() + + { + MUS_LOG("mus: [MUSAVA]: -> CMusAvaCapabilityQueryBase::ContentLC" ) + + CSdpDocument* content = CSdpDocument::NewLC(); + + RStringPool strPool = SdpCodecStringPool::StringPoolL(); + RStringF netType = + MusAvaCapabilityContext::SDPStringL( SdpCodecStringConstants::ENetType ); + + _LIT8(KOriginFieldUser1, "-"); + _LIT8(KSessionName, "-"); + content->SetSessionNameL( KSessionName ); + + TPtrC8 localHost; + RStringF hostType; + + TTime now; + now.UniversalTime(); + TInt64 rand = now.Int64(); + TInt64 sessionID = Math::Rand( rand ); + + hostType = strPool.StringF( SdpCodecStringConstants::EAddressTypeIP4, + SdpCodecStringPool::StringTableL() ); + MUS_LOG( "EAddressTypeIP4 from string pool" ) + + TInetAddr aAddr(0); + iSIPConnection.GetLocalAddrL(aAddr); + TBuf<50> ipAddress; + aAddr.Output(ipAddress); + MUS_LOG_TDESC( "mus: [MUSAVA]: LocalIP Address",ipAddress ) + HBufC8 * ipaddr8=HBufC8::NewLC(ipAddress.Length()); + ipaddr8->Des().Copy(ipAddress); + + MUS_LOG( "mus: [MUSAVA]: SetOriginField" ) + CSdpOriginField* originField = CSdpOriginField::NewL( KOriginFieldUser1, + sessionID, + sessionID, + netType, + hostType, + *ipaddr8); + content->SetOriginField( originField ); + // Connection field + MUS_LOG( "mus: [MUSAVA]: SetConnectionField" ) + CSdpConnectionField* connectionField = + CSdpConnectionField::NewL( netType, hostType,*ipaddr8); + content->SetConnectionField( connectionField ); + CleanupStack::PopAndDestroy(ipaddr8); + + OtherSDPHeadersL(*content); + + MUS_LOG( "mus: [MUSAVA]: Constructing the Sdp Content" ) + CBufFlat* encBuf = CBufFlat::NewL( KMUSAVAMaxLengthOfSDPMessage ); + CleanupStack::PushL( encBuf ); + RBufWriteStream writeStream( *encBuf, 0 ); + writeStream.PushL(); + content->EncodeL( writeStream ); + CleanupStack::PopAndDestroy();//writeStream + HBufC8* textContent = encBuf->Ptr( 0 ).AllocL(); + CleanupStack::PopAndDestroy( encBuf ); + + CleanupStack::PopAndDestroy(content); + + CleanupStack::PushL(textContent); + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQueryBase::ContentLC" ) + return textContent; + } + +// -------------------------------------------------------------------------- +// CMusAvaCapabilityQueryBase::OtherSDPHeadersL +// -------------------------------------------------------------------------- +// +void CMusAvaCapabilityQueryBase::OtherSDPHeadersL( CSdpDocument& aResponseContent ) + + { + MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapabilityQueryBase::OtherSDPHeadersL" ) + + MUS_LOG( "mus: [MUSAVA] Adding application attribute to SDP" ) + //application + CSdpAttributeField* application = CSdpAttributeField::NewLC( + MusAvaCapabilityContext::SDPStringL( + SdpCodecStringConstants::EMediaApplication ), + KCapabilitySwisApplication ); + + aResponseContent.AttributeFields().AppendL( application ); + CleanupStack::Pop( application ); + + MUS_LOG( "mus: [MUSAVA] Adding type attribute to SDP" ) + //type + RStringF typeStr = MusAvaCapabilityContext::SDPStringL( + KCapabilitySDPAttributeNameType ); + CleanupClosePushL( typeStr ); + CSdpAttributeField* type = + CSdpAttributeField::NewL( typeStr, KCapabilitySDPAttributeType ); + CleanupStack::PopAndDestroy();//typeStr + CleanupStack::PushL( type ); + + aResponseContent.AttributeFields().AppendL( type ); + CleanupStack::Pop( type ); + + MUS_LOG( "mus: [MUSAVA] Adding media line to SDP" ) + //media line + CSdpMediaField* mediaLine=CSdpMediaField::NewLC( + MusAvaCapabilityContext::SDPStringL + (SdpCodecStringConstants::EMediaVideo ), + NULL, + MusAvaCapabilityContext::SDPStringL + (SdpCodecStringConstants::EProtocolRtpAvp ), + KCapabilitySwisFormatListH263Only ); + + //adding H.264 codec to SDP + if( !MultimediaSharingSettings::IsAvcDisabled()) + { + MUS_LOG( "mus: [MUSAVA] - Adding avc to supported codec list" ) + // reconstruct media line with H264 and H263 + CleanupStack::PopAndDestroy(mediaLine); + mediaLine = CSdpMediaField::NewLC( + MusAvaCapabilityContext::SDPStringL + (SdpCodecStringConstants::EMediaVideo ), + NULL, + MusAvaCapabilityContext::SDPStringL + (SdpCodecStringConstants::EProtocolRtpAvp ), + KCapabilitySwisFormatList ); + + CSdpFmtAttributeField* rtpMapH264 = + CMusAvaCapability::RtpMapLineLC( KCapabilitySDPAttributeCodecH264, + KCapabilitySDPAttributePayloadTypeH264, + KCapabilitySDPAttributeClockrate ); + + mediaLine->FormatAttributeFields().AppendL( rtpMapH264 ); + CleanupStack::Pop( rtpMapH264 ); + } + + //H.263 codec + MUS_LOG( "mus: [ENGINE] - Adding h263 to supported codec list" ) + CSdpFmtAttributeField* rtpMapH263 = + CMusAvaCapability::RtpMapLineLC( KCapabilitySDPAttributeCodecH263, + KCapabilitySDPAttributePayloadType, + KCapabilitySDPAttributeClockrate ); + + mediaLine->FormatAttributeFields().AppendL( rtpMapH263 ); + CleanupStack::Pop( rtpMapH263 ); + + aResponseContent.MediaFields().AppendL( mediaLine ); + CleanupStack::Pop( mediaLine ); + + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapabilityQueryBase::OtherSDPHeadersL" ) + } + +