diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/ClientResolver/Resolver/src/CSipLaunchingStrategies.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/ClientResolver/Resolver/src/CSipLaunchingStrategies.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,431 @@ +// Copyright (c) 2005-2009 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: +// Name : CSipLaunchingStrategies.cpp +// Part of : SIP Client Resolver +// Version : 1.0 +// + + + +#include "CSipLaunchingStrategies.h" +#include "sdpcodecstringconstants.h" +#include "MSipClients.h" +#include "MSipClient.h" +#include "CSipAcceptContactStrategy2.h" +#include "CSipAcceptContactStrategy.h" +#include "CSipAllowEventsStrategy2.h" +#include "CSipAllowEventsStrategy.h" +#include "CSipRequestStrategy.h" +#include "CSipContentTypeStrategy.h" +#include "CSdpMLineNameStrategy.h" +#include "CSdpMLineMediaStrategy.h" +#include "CSdpMLineTransportStrategy.h" +#include "CSdpRtpmapStrategy.h" +#include "CSdpMediaAttributeStrategy.h" +#include "CSIPOptionsHandler.h" +#include "sipresponse.h" +#include "siprequest.h" +#include "sipcontenttypeheader.h" +#include "siperr.h" +#include "sipstrings.h" +#include "sipstrconsts.h" +#include "sdpdocument.h" +#include "SIPCRLogs.h" +#include "CSIPClientResolver2.h" +#include "sdpmediafield.h" + +const TUint KResponse400 = 400; +const TUint KResponse501 = 501; + +_LIT8(KSdp, "sdp"); +_LIT8(KApplication, "application"); + + +// ---------------------------------------------------------------------------- +// CSipLaunchingStrategies::NewL +// ---------------------------------------------------------------------------- +// +CSipLaunchingStrategies* CSipLaunchingStrategies::NewL( + MSipClients& aSipClients) + { + CSipLaunchingStrategies* self = + new(ELeave)CSipLaunchingStrategies(aSipClients); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// ---------------------------------------------------------------------------- +// CSipLaunchingStrategies::CSipLaunchingStrategies +// ---------------------------------------------------------------------------- +// +CSipLaunchingStrategies::CSipLaunchingStrategies( + MSipClients& aSipClients) + : iSipClients(aSipClients) + { + } + +// ---------------------------------------------------------------------------- +// CSipLaunchingStrategies::ConstructL +// ---------------------------------------------------------------------------- +// +void CSipLaunchingStrategies::ConstructL() + { + // SIP header strategies + CSipContentTypeStrategy* contentTypeStrategy = + CSipContentTypeStrategy::NewLC( iSipClients,NULL ); + iSipStrategies.AppendL( contentTypeStrategy ); + CleanupStack::Pop( contentTypeStrategy ); + + CSipRequestStrategy* requestStrategy = + CSipRequestStrategy::NewLC( iSipClients,NULL,contentTypeStrategy ); + iSipStrategies.AppendL( requestStrategy ); + CleanupStack::Pop( requestStrategy ); + + CSipAllowEventsStrategy* allowEventsStrategy = + CSipAllowEventsStrategy::NewLC( iSipClients, + requestStrategy, + requestStrategy ); + iSipStrategies.InsertL( allowEventsStrategy,0 ); + CleanupStack::Pop( allowEventsStrategy ); + + CSipAllowEventsStrategy2* allowEventsStrategy2 = + CSipAllowEventsStrategy2::NewLC( iSipClients, + requestStrategy, + allowEventsStrategy ); + iSipStrategies.InsertL( allowEventsStrategy2,0 ); + CleanupStack::Pop( allowEventsStrategy2 ); + + CSipAcceptContactStrategy* acceptContactStrategy = + CSipAcceptContactStrategy::NewLC( iSipClients, + allowEventsStrategy, + allowEventsStrategy2 ); + iSipStrategies.InsertL( acceptContactStrategy,0 ); + CleanupStack::Pop( acceptContactStrategy ); + + CSipAcceptContactStrategy2* acceptContactStrategy2 = + CSipAcceptContactStrategy2::NewLC( iSipClients, + allowEventsStrategy2, + acceptContactStrategy ); + iSipStrategies.InsertL( acceptContactStrategy2,0 ); + CleanupStack::Pop( acceptContactStrategy2 ); + + // SDP strategies + CSdpMLineMediaStrategy* mlineMedia = + CSdpMLineMediaStrategy::NewLC(iSipClients); + iSdpStrategies.AppendL(mlineMedia); + CleanupStack::Pop(mlineMedia); + + CSdpMLineTransportStrategy* mlineTransport = + CSdpMLineTransportStrategy::NewLC(iSipClients); + iSdpStrategies.AppendL(mlineTransport); + CleanupStack::Pop(mlineTransport); + + CSdpRtpmapStrategy* rtpmap = + CSdpRtpmapStrategy::NewLC(iSipClients); + iSdpStrategies.AppendL(rtpmap); + CleanupStack::Pop(rtpmap); + + CSdpMediaAttributeStrategy* mediaAttribute = + CSdpMediaAttributeStrategy::NewLC(iSipClients); + iSdpStrategies.AppendL(mediaAttribute); + CleanupStack::Pop(mediaAttribute); + + CSdpMLineNameStrategy* mlineName = + CSdpMLineNameStrategy::NewLC(iSipClients); + iSdpStrategies.AppendL(mlineName); + CleanupStack::Pop(mlineName); + } + +// ---------------------------------------------------------------------------- +// CSipLaunchingStrategies::~CSipLaunchingStrategies +// ---------------------------------------------------------------------------- +// +CSipLaunchingStrategies::~CSipLaunchingStrategies() + { + iSipStrategies.ResetAndDestroy(); + iSdpStrategies.ResetAndDestroy(); + } + +// ---------------------------------------------------------------------------- +// CSipLaunchingStrategies::ApplyL +// ---------------------------------------------------------------------------- +// +CSIPResponse* CSipLaunchingStrategies::ApplyL( + CSIPRequest& aRequest, + RArray& aUids, + CSIPClientResolver2& aClientResolver2 ) + { + SIP_CR_LOG("CSipLaunchingStrategies::ApplyL") + if (aRequest.Method() == SIPStrings::StringF(SipStrConsts::EOptions)) + { + SIP_CR_LOG("CSipLaunchingStrategies::ApplyL EOptions") + if (ClientForOptionsL(aRequest,aUids,aClientResolver2)) + { + return NULL; + } + } + CSIPResponse* response = CheckMethodL(aRequest,aUids,aClientResolver2); + if (response) + { + SIP_CR_LOG("CSipLaunchingStrategies::ApplyL wrong method") + return response; + } + + // Apply SIP header strategies + TBool continueSearch = EFalse; + response = iSipStrategies[0]->ApplyL(aRequest,aUids,continueSearch, + aClientResolver2 ); + + // Apply SDP strategies + if (!response && + continueSearch && + HasSDPContent(const_cast(aRequest))) + { + CSdpDocument* sdpDocument = NULL; + TRAPD (err, sdpDocument = CSdpDocument::DecodeL(aRequest.Content())); + SIP_CR_INT_LOG("CSdpDocument::DecodeL completed with", err) + if (err != KErrNone) + { + if (err == KErrNoMemory) + { + User::Leave(err); + } + return CSIPResponse::NewL(KResponse400, + SIPStrings::StringF(SipStrConsts::EPhraseBadRequest)); + } + CleanupStack::PushL(sdpDocument); + if (!sdpDocument->IsValid()) + { + response = CSIPResponse::NewL(KResponse400, + SIPStrings::StringF(SipStrConsts::EPhraseBadRequest)); + } + else + { + for (TInt j=0; j < iSdpStrategies.Count() && !response; j++) + { + response = iSdpStrategies[j]->ApplyL(*sdpDocument,aUids); + } + } + CleanupStack::PopAndDestroy(sdpDocument); + } + + return response; + } + +// ---------------------------------------------------------------------------- +// CSipLaunchingStrategies::CheckMethodL +// ---------------------------------------------------------------------------- +// +CSIPResponse* CSipLaunchingStrategies::CheckMethodL( + CSIPRequest& aRequest, + RArray& aUids, + CSIPClientResolver2& aClientResolver2) + { + CSIPResponse* response = NULL; + RStringF method = aRequest.Method(); + + if (method == SIPStrings::StringF(SipStrConsts::EOptions)) + { + response = CreateOptionsResponseL(aRequest,aUids,aClientResolver2); + } + else if (method == SIPStrings::StringF(SipStrConsts::EPrack) || + method == SIPStrings::StringF(SipStrConsts::EBye) || + method == SIPStrings::StringF(SipStrConsts::EUpdate) || + method == SIPStrings::StringF(SipStrConsts::EAck)) + { + response = + CSIPResponse::NewL(KResponse400, + SIPStrings::StringF(SipStrConsts::EPhraseBadRequest)); + } + else if (method == SIPStrings::StringF(SipStrConsts::ERegister)) + { + response = + CSIPResponse::NewL(KResponse501, + SIPStrings::StringF(SipStrConsts::EPhraseNotImplemented)); + } + else + { + // NOP + } + + return response; + } + +// ---------------------------------------------------------------------------- +// CSipLaunchingStrategies::HasSDPContent +// ---------------------------------------------------------------------------- +// +TBool CSipLaunchingStrategies::HasSDPContent(CSIPRequest& aRequest) + { + CSIPHeaderBase* header = + aRequest.Header( + SIPStrings::StringF(SipStrConsts::EContentTypeHeader),0); + + if (header) + { + CSIPContentTypeHeader* contentType = + static_cast (header); + + if((contentType->MediaType()).CompareF(KApplication) != 0) + { + return EFalse; + } + + return (contentType->MediaSubtype().CompareF(KSdp) == 0); + } + + return EFalse; + } + +// ---------------------------------------------------------------------------- +// CSipLaunchingStrategies::CreateOptionsResponseL +// ---------------------------------------------------------------------------- +// +CSIPResponse* CSipLaunchingStrategies::CreateOptionsResponseL( + CSIPRequest& aRequest, + RArray& aUids, + CSIPClientResolver2& aClientResolver2) + { + CSIPOptionsHandler* optionsHandler = CSIPOptionsHandler::NewLC(aRequest); + + for (TInt i=0; i < aUids.Count(); i++) + { + MSipClient* client = iSipClients.GetByUID(aUids[i]); + if (client) + { + optionsHandler->AddClientDataL(client->SdpDocument()); + } + } + + for (TInt i=0; i < aClientResolver2.Clients().Count(); i++) + { + CSIPResolvedClient2* client = aClientResolver2.Clients()[i]; + if ( client ) + { + RPointerArray mediaFields; + TRAPD( err,mediaFields = client->SupportedSdpMediasL() ); + if ( err == KErrNoMemory ) + { + User::Leave( err ); + } + if ( !err ) + { + CSipLaunchingStrategies::PushLC(&mediaFields); + optionsHandler->AddClientDataL(&mediaFields); + CleanupStack::Pop();//mediaFields + mediaFields.ResetAndDestroy(); + } + err = 0; + } + } + + CSIPResponse* response = + optionsHandler->CreateResponseL( aUids, + iSipClients, + aClientResolver2); + + CleanupStack::PopAndDestroy(optionsHandler); + + return response; + } + +// ----------------------------------------------------------------------------- +// CSipLaunchingStrategies::PushLC +// ----------------------------------------------------------------------------- +// +void CSipLaunchingStrategies::PushLC(RPointerArray* aArray) + { + CleanupStack::PushL(TCleanupItem(ResetAndDestroyArray,aArray)); + } + +// ----------------------------------------------------------------------------- +// CSipLaunchingStrategies::ResetAndDestroyArray +// ----------------------------------------------------------------------------- +// +void CSipLaunchingStrategies::ResetAndDestroyArray(TAny* anArray) + { + RPointerArray* array = + reinterpret_cast*>(anArray); + if (array) + { + array->ResetAndDestroy(); + } + } + +// ---------------------------------------------------------------------------- +// CSipLaunchingStrategies::ClientForOptionsL +// ---------------------------------------------------------------------------- +// +TBool CSipLaunchingStrategies::ClientForOptionsL( + CSIPRequest& aRequest, + RArray& aUids, + CSIPClientResolver2& aClientResolver2 ) + { + TBool found = EFalse; + if (aRequest.HasHeader( + SIPStrings::StringF(SipStrConsts::EAcceptContactHeader))) + { + CSIPResponse* response = NULL; + RArray tmpUids; + CleanupClosePushL(tmpUids); + for (TInt i=0; i 0); + + CSipAcceptContactStrategy* acceptContact = + CSipAcceptContactStrategy::NewLC( iSipClients,NULL,NULL ); + + TBool dummy = EFalse; + + if ( secondGenerationClientsFound ) + { + CSipAcceptContactStrategy2* acceptContact2 = + CSipAcceptContactStrategy2::NewLC( iSipClients, + NULL, + acceptContact ); + response = acceptContact2->ApplyL( aRequest,tmpUids,dummy, + aClientResolver2 ); + CleanupStack::PopAndDestroy( acceptContact2 ); + } + else + { + response = acceptContact->ApplyL( aRequest,tmpUids,dummy, + aClientResolver2 ); + } + CleanupStack::PopAndDestroy( acceptContact ); + CleanupStack::PushL(response); + + if (!response) + { + found = ETrue; + aUids.Reset(); + // Add only the best match to the results. + // The best match is the first item in the resulting array. + if (tmpUids.Count() > 0) + { + aUids.AppendL(tmpUids[0]); + } + } + delete response; + CleanupStack::Pop(); //response + CleanupStack::PopAndDestroy(&tmpUids); + } + return found; + }