diff -r 000000000000 -r 1bce908db942 natfw/natfwicecandidatehandler/src/ciceconnectivitycheck.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/natfw/natfwicecandidatehandler/src/ciceconnectivitycheck.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,462 @@ +/* +* Copyright (c) 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: Performs connectivity check +* +*/ + + + +#include "natfwcredentials.h" +#include "natfwcandidatepair.h" +#include "natfwcandidate.h" +#include "ciceconnectivitycheck.h" +#include "miceconnchecklistener.h" +#include "natfwbindingbase.h" +#include "ciceconnectionhandler.h" +#include "cicesessiondata.h" + +#include "icecandidatehandlerlogs.h" + +// ======== MEMBER FUNCTIONS ======== + +CIceConnectivityCheck::CIceConnectivityCheck( + MIceConnCheckListener& aClient, + CIceConnectionHandler& aConnHandler, + CIceSessionData& aSessionData ) + : + iState( EIceCheckFrozen ), + iClient( aClient ), + iConnHandler( aConnHandler ), + iSessionData( aSessionData ) + { + } + + +void CIceConnectivityCheck::ConstructL( + const CNATFWCandidate& aLocalCand, + const CNATFWCandidate& aRemoteCand ) + { + __ICEDP( "CIceConnectivityCheck::ConstructL" ) + + __ASSERT_ALWAYS( aLocalCand.ComponentId() == aRemoteCand.ComponentId(), + User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( + aLocalCand.StreamCollectionId() == aRemoteCand.StreamCollectionId(), + User::Leave( KErrArgument ) ); + + iCandidatePair = CNATFWCandidatePair::NewL( aLocalCand, aRemoteCand ); + } + + +CIceConnectivityCheck* CIceConnectivityCheck::NewL( + MIceConnCheckListener& aClient, + const CNATFWCandidate& aLocalCand, + const CNATFWCandidate& aRemoteCand, + CIceConnectionHandler& aConnHandler, + CIceSessionData& aSessionData ) + { + CIceConnectivityCheck* self = CIceConnectivityCheck::NewLC( + aClient, aLocalCand, aRemoteCand, aConnHandler, aSessionData ); + CleanupStack::Pop( self ); + return self; + } + + +CIceConnectivityCheck* CIceConnectivityCheck::NewLC( + MIceConnCheckListener& aClient, + const CNATFWCandidate& aLocalCand, + const CNATFWCandidate& aRemoteCand, + CIceConnectionHandler& aConnHandler, + CIceSessionData& aSessionData ) + { + CIceConnectivityCheck* self = new( ELeave ) + CIceConnectivityCheck( aClient, aConnHandler, aSessionData ); + CleanupStack::PushL( self ); + self->ConstructL( aLocalCand, aRemoteCand ); + return self; + } + + +CIceConnectivityCheck::~CIceConnectivityCheck() + { + __ICEDP( "CIceConnectivityCheck::~CIceConnectivityCheck" ) + + delete iValidatedPair; + if ( iCandidatePair ) + { + iConnHandler.RemoveConnection( + iCandidatePair->LocalCandidate().StreamId(), + iConnectionId ); + } + + delete iCandidatePair; + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::ComparePriorities +// Implements TLinearOrder (descending order). +// --------------------------------------------------------------------------- +// +TInt CIceConnectivityCheck::ComparePriorities( + const CIceConnectivityCheck& aA, + const CIceConnectivityCheck& aB ) + { + return static_cast( + aB.CandidatePair().Priority() - aA.CandidatePair().Priority() ); + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::MatchAddresses +// Implements TIdentityRelation. +// --------------------------------------------------------------------------- +// +TBool CIceConnectivityCheck::MatchAddresses( + const CIceConnectivityCheck& aItem1, + const CIceConnectivityCheck& aItem2 ) + { + const TInetAddr& localAddrA( + aItem1.CandidatePair().LocalCandidate().TransportAddr() ); + const TInetAddr& localAddrB( + aItem2.CandidatePair().LocalCandidate().TransportAddr() ); + const TInetAddr& remoteAddrA( + aItem1.CandidatePair().RemoteCandidate().TransportAddr() ); + const TInetAddr& remoteAddrB( + aItem2.CandidatePair().RemoteCandidate().TransportAddr() ); + + return ( ( TIceUtils::MatchAddresses( localAddrA, localAddrB ) ) + && ( TIceUtils::MatchAddresses( remoteAddrA, remoteAddrB ) ) ); + } + +// Non-derived function + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::Initialize +// --------------------------------------------------------------------------- +// +void CIceConnectivityCheck::Initialize() + { + __ICEDP( "CIceConnectivityCheck::Initialize" ) + + iIsNominated = EFalse; + iResendInProgress = EFalse; + + iState = EIceCheckWaiting; + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::PerformConnCheckL +// USERNAME and MESSAGE-INTEGRITY -attributes are set by connection handler. +// --------------------------------------------------------------------------- +// +void CIceConnectivityCheck::PerformConnCheckL( + TIceCheckType aType, + TUint aPriority, + TUint aRtoValue ) + { + __ICEDP( "CIceConnectivityCheck::PerformConnCheckL" ) + __ICEDP_ADDRLOG( "LOCAL_ADDR", + iCandidatePair->LocalCandidate().TransportAddr() ) + __ICEDP_ADDRLOG( "PEER_ADDR", + iCandidatePair->RemoteCandidate().TransportAddr() ) + + __ASSERT_ALWAYS( + ( EIceCheckWaiting == iState || EIceCheckFrozen == iState ), + User::Leave( KErrNotReady ) ); + + __ASSERT_ALWAYS( ( iCandidatePair->LocalCandidate().Type() == + CNATFWCandidate::ERelay || iCandidatePair->LocalCandidate().Type() == + CNATFWCandidate::EHost ), User::Leave( KErrArgument ) ); + + iType = aType; + iPriority = aPriority; + + if ( 0 == iConnectionId ) + { + iConnectionId = iConnHandler.CreateConnectionL( *iCandidatePair ); + } + + iConnHandler.PerformConnCheckL( + StreamId(), iConnectionId, iPriority, EFalse, + aRtoValue, iCandidatePair->RemoteCandidate().TransportAddr(), + *this ); + + iState = EIceCheckInProgress; + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::PerformNominationL +// --------------------------------------------------------------------------- +// +void CIceConnectivityCheck::PerformNominationL( TUint aRtoValue ) + { + __ICEDP( "CIceConnectivityCheck::PerformNominationL" ) + __ICEDP_ADDRLOG( "LOCAL_ADDR", + iCandidatePair->LocalCandidate().TransportAddr() ) + __ICEDP_ADDRLOG( "PEER_ADDR", + iCandidatePair->RemoteCandidate().TransportAddr() ) + + __ASSERT_ALWAYS( + EIceCheckSucceed == iState || EIceCheckInProgress == iState, + User::Leave( KErrNotReady ) ); + + iIsNominated = ETrue; + + if ( EIceCheckSucceed == iState ) + { + iConnHandler.PerformConnCheckL( + StreamId(), iConnectionId, iPriority, ETrue, aRtoValue, + iCandidatePair->RemoteCandidate().TransportAddr(), *this ); + iResendInProgress = ETrue; + iState = EIceCheckInProgress; + } + else + { + ASSERT( EFalse ); + } + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::Nominated +// --------------------------------------------------------------------------- +// +TBool CIceConnectivityCheck::Nominated() const + { + __ICEDP_INT1( "CIceConnectivityCheck::Nominated:", iIsNominated ) + + return iIsNominated; + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::SetRemoteCheckInfo +// --------------------------------------------------------------------------- +// +void CIceConnectivityCheck::SetRemoteCheckInfo( + TUint aPriority, TBool aFavored ) + { + __ICEDP( "CIceConnectivityCheck::SetRemoteCheckInfo" ) + + iRemotePriority = aPriority; + iRemoteFavored = aFavored; + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::Cancel +// --------------------------------------------------------------------------- +// +void CIceConnectivityCheck::Cancel() + { + iConnHandler.CancelCheck( StreamId(), iConnectionId, + iCandidatePair->RemoteCandidate().TransportAddr() ); + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::StreamId +// --------------------------------------------------------------------------- +// +TUint CIceConnectivityCheck::StreamId() const + { + return iCandidatePair->LocalCandidate().StreamId(); + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::ComponentId +// --------------------------------------------------------------------------- +// +TUint CIceConnectivityCheck::ComponentId() const + { + return iCandidatePair->LocalCandidate().ComponentId(); + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::State +// --------------------------------------------------------------------------- +// +CIceConnectivityCheck::TIceCheckState CIceConnectivityCheck::State() const + { + return iState; + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::StreamCollectionId +// --------------------------------------------------------------------------- +// +TUint CIceConnectivityCheck::StreamCollectionId() const + { + return iCandidatePair->LocalCandidate().StreamCollectionId(); + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::ValidatedPair +// --------------------------------------------------------------------------- +// +const CNATFWCandidatePair* CIceConnectivityCheck::ValidatedPair() const + { + return iValidatedPair; + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::CandidatePair +// --------------------------------------------------------------------------- +// +const CNATFWCandidatePair& CIceConnectivityCheck::CandidatePair() const + { + return *iCandidatePair; + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::ConnCheckCompletedL +// --------------------------------------------------------------------------- +// +void CIceConnectivityCheck::ConnCheckCompletedL( + TInt aCompletionCode, +#ifdef _DEBUG + const TInetAddr& aLocalAddr, +#else + const TInetAddr& /*aLocalAddr*/, +#endif + const TInetAddr& aPeerAddr, + const TInetAddr& aMappedAddr ) + { + __ICEDP_INT1( "CIceConnectivityCheck::ConnCheckCompletedL, COMPLCODE", + aCompletionCode ) + + __ICEDP_ADDRLOG( "LOCAL_ADDR", aLocalAddr ) + __ICEDP_ADDRLOG( "PEER_ADDR", aPeerAddr ) + __ICEDP_ADDRLOG( "MAPPED_ADDR", aMappedAddr ) + + __ASSERT_DEBUG( EIceCheckInProgress == iState, + User::Leave( KErrNotReady ) ); + + TInt completionCode = aCompletionCode; + if ( !TIceUtils::MatchAddresses( aPeerAddr, + iCandidatePair->RemoteCandidate().TransportAddr() ) ) + { + completionCode = KErrCouldNotConnect; + } + + if ( KErrNone != completionCode ) + { + iState = EIceCheckFailed; + if ( iResendInProgress ) + { + iResendInProgress = EFalse; + iClient.NominationCompletedL( + completionCode, *this, *iValidatedPair ); + } + else + { + iClient.CheckCompletedL( completionCode, *this, NULL ); + } + + return; + } + + if ( iResendInProgress ) + { + iResendInProgress = EFalse; + if ( iIsNominated ) + { + iValidatedPair->SetSelected( ETrue ); + iCandidatePair->SetSelected( ETrue ); + } + + iClient.NominationCompletedL( completionCode, *this, + *iValidatedPair ); + } + else + { + iState = EIceCheckSucceed; + iValidatedPair = CreateValidatedPairL( aMappedAddr ); + + CNATFWCandidatePair* validatedPair + = CNATFWCandidatePair::NewL( *iValidatedPair ); + iClient.CheckCompletedL( completionCode, *this, + validatedPair ); + } + } + + +// --------------------------------------------------------------------------- +// CIceConnectivityCheck::CreateValidatedPairL +// ICE-17, 7.1.2.2.2, Constructing a Valid Pair +// --------------------------------------------------------------------------- +// +CNATFWCandidatePair* CIceConnectivityCheck::CreateValidatedPairL( + const TInetAddr& aMappedAddr ) + { + __ICEDP( "CIceConnectivityCheck::CreateValidatedPairL" ) + + const CNATFWCandidate* knownLocalCand + = iSessionData.FindLocalCandidate( aMappedAddr ); + + CNATFWCandidate* validatedLocalCand = NULL; + if ( knownLocalCand ) + { + validatedLocalCand = CNATFWCandidate::NewLC( *knownLocalCand ); + } + else + { + // Peer reflexive candidate + validatedLocalCand = CNATFWCandidate::NewLC( + iCandidatePair->LocalCandidate() ); + validatedLocalCand->SetTransportAddrL( aMappedAddr ); + validatedLocalCand->SetType( CNATFWCandidate::EPeerReflexive ); + validatedLocalCand->SetPriority( iPriority ); + } + + CNATFWCandidate* remoteCand + = CNATFWCandidate::NewLC( iCandidatePair->RemoteCandidate() ); + if ( EIceCheckTypeTriggered == iType ) + { + remoteCand->SetPriority( iRemotePriority ); + } + + CNATFWCandidatePair* validatedPair = CNATFWCandidatePair::NewLC( + *validatedLocalCand, *remoteCand ); + + if ( iIsNominated ) + { + // ICE-17, 7.1.2.2.4. Updating the Nominated Flag + validatedPair->SetSelected( ETrue ); + iCandidatePair->SetSelected( ETrue ); + } + else + { + if ( EIceCheckTypeTriggered == iType && iRemoteFavored ) + { + // ICE-17, 7.2.1.5. Updating the Nominated Flag + validatedPair->SetSelected( ETrue ); + iCandidatePair->SetSelected( ETrue ); + } + } + + CleanupStack::Pop( validatedPair ); + CleanupStack::PopAndDestroy( remoteCand ); + CleanupStack::PopAndDestroy( validatedLocalCand ); + return validatedPair; + }