natfw/natfwicecandidatehandler/src/cicechecklist.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "natfwcandidate.h"
       
    22 #include "natfwcandidatepair.h"
       
    23 #include "cicechecklist.h"
       
    24 #include "cicecheckprioritizer.h"
       
    25 #include "cicecandidateprioritizer.h"
       
    26 #include "ciceconnectivitycheck.h"
       
    27 #include "cicesessiondata.h"
       
    28 #include "micechecklistobserver.h"
       
    29 #include "cicevalidlist.h"
       
    30 #include "icecandidatehandlerdefs.h"
       
    31 #include "icecandidatehandlerlogs.h"
       
    32 
       
    33 const TUint KComponentIdRtp = 1;
       
    34 
       
    35 // ======== MEMBER FUNCTIONS ========
       
    36 
       
    37 CIceCheckList::CIceCheckList(
       
    38         MIceChecklistObserver& aClient,
       
    39         TUint aStreamCollectionId,
       
    40         CIceSessionData& aSessionData,
       
    41         CIceConnectionHandler& aConnHandler )
       
    42     :
       
    43     iStreamCollectionId( aStreamCollectionId ),
       
    44     iClient( aClient ),
       
    45     iSessionData( aSessionData ),
       
    46     iConnHandler( aConnHandler )
       
    47     {
       
    48     }
       
    49 
       
    50 
       
    51 void CIceCheckList::ConstructL()
       
    52     {
       
    53     iCheckPrioritizer = CIceCheckPrioritizer::NewL();
       
    54     iCandPrioritizer = CIceCandidatePrioritizer::NewL( 
       
    55         iSessionData.Domain() );
       
    56     iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
    57     iValidList = CIceValidList::NewL( iStreamCollectionId );
       
    58     GenerateCheckListL( iChecks );
       
    59     }
       
    60 
       
    61 
       
    62 CIceCheckList* CIceCheckList::NewL(
       
    63         MIceChecklistObserver& aClient,
       
    64         TUint aStreamCollectionId,
       
    65         CIceSessionData& aSessionData,
       
    66         CIceConnectionHandler& aConnHandler )
       
    67     {
       
    68     CIceCheckList* self 
       
    69         = CIceCheckList::NewLC( aClient, aStreamCollectionId, 
       
    70         aSessionData, aConnHandler );
       
    71     CleanupStack::Pop( self );
       
    72     return self;
       
    73     }
       
    74 
       
    75 
       
    76 CIceCheckList* CIceCheckList::NewLC(
       
    77         MIceChecklistObserver& aClient,
       
    78         TUint aStreamCollectionId,
       
    79         CIceSessionData& aSessionData,
       
    80         CIceConnectionHandler& aConnHandler )
       
    81     {
       
    82     CIceCheckList* self 
       
    83         = new( ELeave ) CIceCheckList( 
       
    84         aClient, aStreamCollectionId, aSessionData, aConnHandler );
       
    85     CleanupStack::PushL( self );
       
    86     self->ConstructL();
       
    87     return self;
       
    88     }
       
    89 
       
    90 
       
    91 CIceCheckList::~CIceCheckList()
       
    92     {
       
    93     __ICEDP( "CIceCheckList::~CIceCheckList" )
       
    94     
       
    95     iChecks.ResetAndDestroy();
       
    96     iCheckQue.Close();
       
    97     delete iCheckPrioritizer;
       
    98     delete iCandPrioritizer;
       
    99     delete iTimer;
       
   100     delete iValidList;
       
   101     iComponentIds.Close();
       
   102     iSelectedPairs.ResetAndDestroy();
       
   103     }
       
   104 
       
   105 
       
   106 // ---------------------------------------------------------------------------
       
   107 // CIceCheckList::TimerFired
       
   108 // ---------------------------------------------------------------------------
       
   109 //
       
   110 TInt CIceCheckList::TimerFired( TAny* aObject )
       
   111     {
       
   112     if ( aObject )
       
   113         {
       
   114         CIceCheckList* list = reinterpret_cast<CIceCheckList*>( aObject );
       
   115         TRAPD( error, list->OnTimerFiredL() )
       
   116         if ( error )
       
   117             {
       
   118             __ICEDP_INT1( "CIceCheckList::TimerFired, ERR:", error )
       
   119             if ( KErrNoMemory == error )
       
   120                 {
       
   121                 TRAP_IGNORE( list->SetStateL( EIceCheckListFailed ) )
       
   122                 }
       
   123             else
       
   124                 {
       
   125                 ASSERT( EFalse );
       
   126                 }
       
   127             }
       
   128         
       
   129         return 1;
       
   130         }
       
   131     else
       
   132         {
       
   133         __ICEDP( "CIceCheckList::TimerFired, ELSE" )
       
   134         ASSERT( EFalse );
       
   135         return 0;   // lint #527
       
   136         }
       
   137     }
       
   138 
       
   139 
       
   140 // Non-derived function
       
   141 
       
   142 // ---------------------------------------------------------------------------
       
   143 // CIceCheckList::State
       
   144 // ---------------------------------------------------------------------------
       
   145 //
       
   146 CIceCheckList::TIceCheckListState CIceCheckList::State() const
       
   147     {
       
   148     return iState;
       
   149     }
       
   150 
       
   151 
       
   152 // ---------------------------------------------------------------------------
       
   153 // CIceCheckList::StreamCollectionId()
       
   154 // ---------------------------------------------------------------------------
       
   155 //
       
   156 TUint CIceCheckList::StreamCollectionId() const
       
   157     {
       
   158     return iStreamCollectionId;
       
   159     }
       
   160 
       
   161 
       
   162 // ---------------------------------------------------------------------------
       
   163 // CIceCheckList::InitializeCheckListL()
       
   164 // Used to initialize check list corresponding first SDP mediastream.
       
   165 // ICE-17, section 5.7.4.
       
   166 // ---------------------------------------------------------------------------
       
   167 //
       
   168 void CIceCheckList::InitializeCheckListL()
       
   169     {
       
   170     __ICEDP( "CIceCheckList::InitializeCheckListL" )
       
   171     __ASSERT_DEBUG( iChecks.Count(), User::Leave( KErrNotReady ) );
       
   172     
       
   173     TUint lowestComponentId = LowestComponentId( iComponentIds );
       
   174     
       
   175     CDesC8ArrayFlat* foundations 
       
   176         = FoundationsForCollectionL( iStreamCollectionId );
       
   177     
       
   178     TInt foundationCount( foundations->Count() );
       
   179     for ( TInt i(0); i < foundationCount; ++i )
       
   180         {
       
   181         // inside foundation group set lowest component id waiting
       
   182         TInt checkIndex( iChecks.Count() );
       
   183         TBool checkInitialized( EFalse );
       
   184         
       
   185         while ( ( checkIndex-- ) && ( !checkInitialized ) )
       
   186             {
       
   187             CIceConnectivityCheck& check( *iChecks[checkIndex] );
       
   188             if ( check.CandidatePair().Foundation() 
       
   189                     == foundations->MdcaPoint(i)
       
   190                 && check.ComponentId() == lowestComponentId )
       
   191                 {
       
   192                 check.Initialize();
       
   193                 checkInitialized = ETrue;
       
   194                 }
       
   195             }
       
   196         }
       
   197     
       
   198     delete foundations;
       
   199     }
       
   200 
       
   201 
       
   202 // ---------------------------------------------------------------------------
       
   203 // CIceCheckList::InitializeCheckListL
       
   204 // ICE-17, 7.1.2.2.3, Updating Pair States.
       
   205 // ---------------------------------------------------------------------------
       
   206 //
       
   207 void CIceCheckList::InitializeCheckListL( const TDesC8& aFoundation )
       
   208     {
       
   209     __ICEDP( "CIceCheckList::InitializeCheckListL" )
       
   210     __ASSERT_DEBUG( iChecks.Count(), User::Leave( KErrNotReady ) );
       
   211     
       
   212     TBool initComplete( EFalse );
       
   213     TInt count( iChecks.Count() );
       
   214     for ( TInt i = 0; i < count; ++i )
       
   215         {
       
   216         if ( CIceConnectivityCheck::EIceCheckFrozen == iChecks[i]->State()
       
   217             && iChecks[i]->CandidatePair().Foundation() == aFoundation )
       
   218             {
       
   219             iChecks[i]->Initialize();
       
   220             initComplete = ETrue;
       
   221             }
       
   222         }
       
   223     
       
   224     if ( !initComplete && CheckListFrozen() )
       
   225         {
       
   226         InitializeCheckListL();
       
   227         }
       
   228     }
       
   229 
       
   230 
       
   231 // ---------------------------------------------------------------------------
       
   232 // CIceCheckList::StartPerformChecksL()
       
   233 // ---------------------------------------------------------------------------
       
   234 //
       
   235 void CIceCheckList::StartPerformChecksL( 
       
   236         const TTimeIntervalMicroSeconds32& anInterval )
       
   237     {
       
   238     __ICEDP( "CIceCheckList::StartPerformChecksL" )
       
   239     
       
   240     iInterval = anInterval;
       
   241     SetStateL( EIceCheckListRunning );
       
   242     }
       
   243 
       
   244 
       
   245 // ---------------------------------------------------------------------------
       
   246 // CIceCheckList::RestartCheckListL()
       
   247 // ---------------------------------------------------------------------------
       
   248 //
       
   249 void CIceCheckList::RestartCheckListL(
       
   250         const TTimeIntervalMicroSeconds32& anInterval )
       
   251     {
       
   252     __ICEDP( "CIceCheckList::RestartCheckListL" )
       
   253     __ASSERT_ALWAYS( EIceCheckListCompleted == State(), 
       
   254         User::Leave( KErrNotReady ) );
       
   255     
       
   256     iValidList->FlushValidList();
       
   257     iChecks.ResetAndDestroy();
       
   258     GenerateCheckListL( iChecks );
       
   259     
       
   260     iInterval = anInterval;
       
   261     SetStateL( EIceCheckListRunning );
       
   262     }
       
   263 
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // CIceCheckList::UpdateCheckListL()
       
   267 // Controlling peer has selected candidate pairs to be used.
       
   268 // ICE-17, 9.2.2.3. Existing Media Streams and remote-candidates.
       
   269 // ---------------------------------------------------------------------------
       
   270 //
       
   271 void CIceCheckList::UpdateCheckListL( 
       
   272         RPointerArray<CNATFWCandidatePair>& aPeerSelectedPairs )
       
   273     {
       
   274     __ICEDP( "CIceCheckList::UpdateIceProcessingL" )
       
   275     __ASSERT_DEBUG( EIceCheckListRunning == State(), 
       
   276         User::Leave( KErrNotReady ) );
       
   277     __ASSERT_ALWAYS( !iSelectedPairs.Count(), 
       
   278         User::Leave( KErrAlreadyExists ) );
       
   279     
       
   280     TInt numOfSelectedComps( aPeerSelectedPairs.Count() );
       
   281     for ( TInt i( 0 ); i < numOfSelectedComps; ++i )
       
   282         {
       
   283         CNATFWCandidatePair* pair 
       
   284             = CNATFWCandidatePair::NewLC( *aPeerSelectedPairs[i] );
       
   285         iSelectedPairs.AppendL( pair );
       
   286         CleanupStack::Pop( pair );
       
   287         }
       
   288     
       
   289     DoLosingPairProcessingL( iSelectedPairs );
       
   290     UpdateCheckListStateL();
       
   291     }
       
   292 
       
   293 
       
   294 // ---------------------------------------------------------------------------
       
   295 // CIceCheckList::UpdateCheckListL()
       
   296 // Peer has added new remote candidates to the session negotiation.
       
   297 // ICE-17, 9.3.1.4. ICE Continuing for Existing Media Stream.
       
   298 // ---------------------------------------------------------------------------
       
   299 //
       
   300 void CIceCheckList::UpdateCheckListL( 
       
   301         RPointerArray<CNATFWCandidate>& /*aRemoteCands*/ )
       
   302     {
       
   303     __ICEDP( "CIceCheckList::UpdateIceProcessingL" )
       
   304     __ASSERT_DEBUG( EIceCheckListRunning == State(), 
       
   305         User::Leave( KErrNotReady ) );
       
   306     
       
   307     RPointerArray<CIceConnectivityCheck> newCheckList;
       
   308     CleanupResetAndDestroyPushL( newCheckList );
       
   309     GenerateCheckListL( newCheckList );
       
   310     
       
   311     // Add new checks to the checklist
       
   312     for ( TInt i( newCheckList.Count() - 1 ); i >= 0; --i )
       
   313         {
       
   314         CIceConnectivityCheck* newCheck( newCheckList[i] );
       
   315         
       
   316         TInt ind = iChecks.Find( 
       
   317             newCheck, CIceConnectivityCheck::MatchAddresses );
       
   318         
       
   319         // All new checks are in frozen state initially
       
   320         if ( KErrNotFound == ind )
       
   321             {
       
   322             iChecks.InsertInOrderL( newCheck,
       
   323                 CIceConnectivityCheck::ComparePriorities );
       
   324             newCheckList.Remove( i );
       
   325             }
       
   326         }
       
   327     
       
   328     TBool rtpComponentFound( EFalse );
       
   329     TInt ind( iChecks.Count() - 1 );
       
   330     while( ( !rtpComponentFound ) && ( 0 <= ind ) )
       
   331         {
       
   332         if ( KComponentIdRtp == iChecks[ind]->ComponentId()
       
   333             && CIceConnectivityCheck::EIceCheckSucceed 
       
   334                 == iChecks[ind]->State() )
       
   335             {
       
   336             rtpComponentFound = ETrue;
       
   337             InitializeCheckList( 
       
   338                 iChecks[ind]->CandidatePair().Foundation(), 
       
   339                 KComponentIdRtp );
       
   340             
       
   341             if ( iValidList->HasPairForComponents( iComponentIds ) )
       
   342                 {
       
   343                 // Start checks in other check lists for checks of same type
       
   344                 iClient.ComponentsHaveValidPairsL( 
       
   345                     *this, iChecks[ind]->CandidatePair().Foundation() );
       
   346                 }
       
   347             }
       
   348         
       
   349         ind--;
       
   350         }
       
   351     
       
   352     CleanupStack::PopAndDestroy( &newCheckList );
       
   353     }
       
   354 
       
   355 
       
   356 // ---------------------------------------------------------------------------
       
   357 // CIceCheckList::GenerateCheckListL()
       
   358 // ---------------------------------------------------------------------------
       
   359 //
       
   360 void CIceCheckList::GenerateCheckListL( 
       
   361         RPointerArray<CIceConnectivityCheck>& aCheckList )
       
   362     {
       
   363     __ICEDP( "CIceCheckList::GenerateCheckListL" )
       
   364     
       
   365     RPointerArray<CNATFWCandidate> localCandidates;
       
   366     RPointerArray<CNATFWCandidate> remoteCandidates;
       
   367     CleanupClosePushL( localCandidates );
       
   368     CleanupClosePushL( remoteCandidates );
       
   369     
       
   370     iSessionData.GetLocalCandidates(
       
   371         iStreamCollectionId,
       
   372         localCandidates );
       
   373     
       
   374     iSessionData.GetRemoteCandidatesL(
       
   375         iStreamCollectionId,
       
   376         remoteCandidates );
       
   377     
       
   378     __ASSERT_ALWAYS( localCandidates.Count() && remoteCandidates.Count(),
       
   379         User::Leave( KErrNotReady ) );
       
   380     
       
   381     PairCandidatesL( aCheckList, localCandidates, remoteCandidates );
       
   382     CleanupStack::PopAndDestroy( &remoteCandidates );
       
   383     CleanupStack::PopAndDestroy( &localCandidates );
       
   384     
       
   385     iCheckPrioritizer->PrioritizeChecks( aCheckList, iSessionData.Role() );
       
   386     aCheckList.Sort( CIceConnectivityCheck::ComparePriorities );
       
   387     PruneChecksL( aCheckList );
       
   388     
       
   389 #ifdef _DEBUG
       
   390     __ICEDP( "CIceCheckList::GenerateCheckListL, LIST AFTER PRUNING" )
       
   391     TInt count( aCheckList.Count() );
       
   392     for ( TInt i(0); i < count; ++i )
       
   393         {
       
   394         __ICEDP_ADDRLOG( "LOCAL_ADDR", 
       
   395             aCheckList[i]->CandidatePair().LocalCandidate().TransportAddr() )
       
   396         
       
   397         __ICEDP_ADDRLOG( "PEER_ADDR", 
       
   398             aCheckList[i]->CandidatePair().RemoteCandidate().TransportAddr() )
       
   399         }
       
   400 #endif
       
   401     
       
   402     GetComponentIdsL( iComponentIds );
       
   403     }
       
   404 
       
   405 
       
   406 // ---------------------------------------------------------------------------
       
   407 // CIceCheckList::PairCandidatesL
       
   408 // ---------------------------------------------------------------------------
       
   409 //
       
   410 void CIceCheckList::PairCandidatesL(
       
   411     RPointerArray<CIceConnectivityCheck>& aCheckList,
       
   412     RPointerArray<CNATFWCandidate>& aLocalCands,
       
   413     RPointerArray<CNATFWCandidate>& aRemoteCands )
       
   414     {
       
   415     __ICEDP( "CIceCheckList::PairCandidatesL" )
       
   416     
       
   417     CNATFWCandidate* lCand( NULL );
       
   418     CNATFWCandidate* rCand( NULL );
       
   419     
       
   420     TInt lInd = aLocalCands.Count();
       
   421     while ( lInd-- )
       
   422         {
       
   423         lCand = aLocalCands[lInd];
       
   424         
       
   425         TInt rInd = aRemoteCands.Count();
       
   426         while ( rInd-- )
       
   427             {
       
   428             rCand = aRemoteCands[rInd];
       
   429             
       
   430             if ( CompatibleCandidates( *lCand, *rCand ) )
       
   431                 {
       
   432                 CIceConnectivityCheck* check
       
   433                     = CIceConnectivityCheck::NewLC( *this, *lCand, *rCand, 
       
   434                     iConnHandler, iSessionData );
       
   435                 
       
   436                 aCheckList.AppendL( check );
       
   437                 CleanupStack::Pop( check );
       
   438                 }
       
   439             }
       
   440         }
       
   441     }
       
   442 
       
   443 
       
   444 // ---------------------------------------------------------------------------
       
   445 // CIceCheckList::CompatibleCandidates
       
   446 // According to ICE-17, 5.7.1. and ICE-TCP-03, 4.1.
       
   447 // ---------------------------------------------------------------------------
       
   448 //
       
   449 TBool CIceCheckList::CompatibleCandidates( 
       
   450         const CNATFWCandidate& aCand1, const CNATFWCandidate& aCand2 ) const
       
   451     {
       
   452     __ICEDP( "CIceCheckList::CompatibleCandidates" )
       
   453     
       
   454     TUint protocol( aCand1.TransportProtocol() );
       
   455     if ( protocol != aCand2.TransportProtocol()
       
   456         || aCand1.TransportAddr().Family() != aCand2.TransportAddr().Family()
       
   457         || aCand1.ComponentId() != aCand2.ComponentId() )
       
   458         {
       
   459         return EFalse;
       
   460         }
       
   461     
       
   462     if ( KProtocolInetUdp == protocol )
       
   463         {
       
   464         return ETrue;
       
   465         }
       
   466     else
       
   467         {
       
   468         // we have not TCP support yet
       
   469         return EFalse;
       
   470         }
       
   471     }
       
   472 
       
   473 
       
   474 // ---------------------------------------------------------------------------
       
   475 // CIceCheckList::PruneChecksL
       
   476 // ICE-17, 5.7.3 Pruning the pairs.
       
   477 // Procedures of ICE-TCP-03, 4.1. to be added.
       
   478 // ---------------------------------------------------------------------------
       
   479 //
       
   480 void CIceCheckList::PruneChecksL( 
       
   481         RPointerArray<CIceConnectivityCheck>& aChecks )
       
   482     {
       
   483     __ICEDP_INT1( "CIceCheckList::PruneChecksL start, COUNT:", aChecks.Count() )
       
   484     
       
   485     // Replace server reflexive local candidate of the check by corresponding
       
   486     // base candidate.
       
   487     ReplaceReflexiveCandidatesWithBaseL( aChecks );
       
   488     
       
   489     // Remove redundant checks.
       
   490     for ( TInt i( aChecks.Count() - 1 ); 0 <= i; --i )
       
   491         {
       
   492         TInt matchInd = aChecks.Find( aChecks[i],
       
   493             CIceConnectivityCheck::MatchAddresses );
       
   494         
       
   495         if ( KErrNotFound != matchInd && matchInd != i )
       
   496             {
       
   497             delete aChecks[i];
       
   498             aChecks.Remove( i );
       
   499             }
       
   500         }
       
   501     
       
   502     __ICEDP_INT1( "CIceCheckList::PruneChecksL end, COUNT:", aChecks.Count() )
       
   503     }
       
   504 
       
   505 
       
   506 // ---------------------------------------------------------------------------
       
   507 // CIceCheckList::ReplaceReflexiveCandidatesWithBaseL
       
   508 // ---------------------------------------------------------------------------
       
   509 //
       
   510 void CIceCheckList::ReplaceReflexiveCandidatesWithBaseL( 
       
   511         RPointerArray<CIceConnectivityCheck>& aChecks )
       
   512     {
       
   513     for ( TInt i( aChecks.Count() - 1 ); i >= 0; --i )
       
   514         {
       
   515         CNATFWCandidate& localCand = const_cast<CNATFWCandidate&>
       
   516             ( aChecks[ i ]->CandidatePair().LocalCandidate() );
       
   517         
       
   518         if ( CNATFWCandidate::EServerReflexive == localCand.Type() )
       
   519             {
       
   520             TInt numOfChecks( aChecks.Count() );
       
   521             for ( TInt j( 0 ); j < numOfChecks; ++j )
       
   522                 {
       
   523                 const CNATFWCandidate& baseCand
       
   524                      = aChecks[ j ]->CandidatePair().LocalCandidate();
       
   525                 if ( CNATFWCandidate::EHost == baseCand.Type()
       
   526                     && TIceUtils::MatchAddresses( 
       
   527                         localCand.Base(), baseCand.Base() ) )
       
   528                     {
       
   529                     localCand.SetTransportAddrL( baseCand.Base() );
       
   530                     localCand.SetType( CNATFWCandidate::EHost );
       
   531                     localCand.SetFoundationL( baseCand.Foundation() );
       
   532                     localCand.SetPriority( baseCand.Priority() );
       
   533                     }
       
   534                 }
       
   535             }
       
   536         }
       
   537     }
       
   538 
       
   539 
       
   540 // ---------------------------------------------------------------------------
       
   541 // CIceCheckList::OnTimerFiredL
       
   542 // If triggered check queue contains items, top-most triggered check is sent.
       
   543 // Otherwise an ordinary check is sent. ICE-17, 5.8. Scheduling checks.
       
   544 // ---------------------------------------------------------------------------
       
   545 //
       
   546 void CIceCheckList::OnTimerFiredL()
       
   547     {
       
   548     __ICEDP( "CIceCheckList::OnTimerFiredL" )
       
   549     
       
   550     TBool found = DequeueCheckL();
       
   551     if ( found )
       
   552         {
       
   553         return;
       
   554         }
       
   555     
       
   556     // Find highest priority check in waiting state
       
   557     TInt ind = FindCheckInState( CIceConnectivityCheck::EIceCheckWaiting );
       
   558     if ( KErrNotFound != ind )
       
   559         {
       
   560         TUint priority = PriorityForPeerReflCandL( 
       
   561             iChecks[ind]->CandidatePair().LocalCandidate() );
       
   562         iChecks[ind]->PerformConnCheckL( 
       
   563             CIceConnectivityCheck::EIceCheckTypePeriodic, priority,
       
   564             RetransmissionTimeOut() );
       
   565         
       
   566         return;
       
   567         }
       
   568     
       
   569     ind = FindCheckInState( CIceConnectivityCheck::EIceCheckFrozen );
       
   570     if ( KErrNotFound != ind )
       
   571         {
       
   572         iChecks[ind]->Initialize();
       
   573         TUint priority = PriorityForPeerReflCandL( 
       
   574             iChecks[ind]->CandidatePair().LocalCandidate() );
       
   575         iChecks[ind]->PerformConnCheckL( 
       
   576             CIceConnectivityCheck::EIceCheckTypePeriodic, priority,
       
   577             RetransmissionTimeOut() );
       
   578         
       
   579         return;
       
   580         }
       
   581     
       
   582     iTimer->Cancel();
       
   583     }
       
   584 
       
   585 
       
   586 // ---------------------------------------------------------------------------
       
   587 // CIceCheckList::PriorityForPeerReflCandL
       
   588 // ---------------------------------------------------------------------------
       
   589 //
       
   590 TUint CIceCheckList::PriorityForPeerReflCandL( 
       
   591         const CNATFWCandidate& aLocalCandidate ) const
       
   592     {
       
   593     __ICEDP( "CIceCheckList::PriorityForTentativePeerReflCandL" )
       
   594     
       
   595     CNATFWCandidate* candidate = CNATFWCandidate::NewLC( aLocalCandidate );
       
   596     candidate->SetType( CNATFWCandidate::EPeerReflexive );
       
   597     iCandPrioritizer->PrioritizeL( *candidate );
       
   598     TUint priority( candidate->Priority() );
       
   599     CleanupStack::PopAndDestroy( candidate );
       
   600     
       
   601     return priority;
       
   602     }
       
   603 
       
   604 
       
   605 // ---------------------------------------------------------------------------
       
   606 // CIceCheckList::STUNRequestReceivedL
       
   607 // Resolve local and remote candidates and set up them for actual handler.
       
   608 // ---------------------------------------------------------------------------
       
   609 //
       
   610 void CIceCheckList::STUNRequestReceivedL( const TInetAddr& aLocalAddr,
       
   611         const TInetAddr& aFromAddr, const TInetAddr& aPeerAddr,
       
   612         TUint aPriority, TBool aRemoteFavored )
       
   613     {
       
   614     __ICEDP( "CIceCheckList::STUNRequestReceivedL" )
       
   615     if ( ( State() != EIceCheckListRunning ) 
       
   616         && ( State() != EIceCheckListCompleted ) )
       
   617         {
       
   618         SetStateL( EIceCheckListRunning );
       
   619         }
       
   620     
       
   621     // Find real local candidate where request was sent to
       
   622     const CNATFWCandidate* localCand = NULL;
       
   623     TBool relayUsed = !TIceUtils::MatchAddresses( aFromAddr, aPeerAddr );
       
   624     if ( relayUsed )
       
   625         {
       
   626         __ICEDP( "CIceCheckList::STUNRequestReceivedL, RELAY USED" )
       
   627         
       
   628         // Find out media component type (RTP/RTCP)
       
   629         localCand = iSessionData.FindLocalCandidate( aLocalAddr );
       
   630         TUint componentId = localCand->ComponentId();
       
   631         localCand = iSessionData.FindLocalCandidate( 
       
   632             iStreamCollectionId, componentId, CNATFWCandidate::ERelay );
       
   633         }
       
   634     else
       
   635         {
       
   636         localCand = iSessionData.FindLocalCandidate( aLocalAddr );
       
   637         }
       
   638     
       
   639     __ASSERT_ALWAYS( NULL != localCand, User::Leave( KErrNotFound ) );
       
   640     
       
   641     const CNATFWCandidate* remoteCand 
       
   642         = iSessionData.FindRemoteCandidate( aPeerAddr );
       
   643     CNATFWCandidate* newRemoteCand = NULL;
       
   644     if ( remoteCand )
       
   645         {
       
   646         newRemoteCand = CNATFWCandidate::NewLC( *remoteCand );
       
   647         }
       
   648     else
       
   649         {
       
   650         // ICE-17, 7.2.1.3.  Learning Peer Reflexive (remote) Candidates
       
   651         newRemoteCand = CNATFWCandidate::NewLC();
       
   652         newRemoteCand->SetTransportAddrL( aPeerAddr );
       
   653         newRemoteCand->SetType( CNATFWCandidate::EPeerReflexive );
       
   654         newRemoteCand->SetStreamCollectionId( localCand->StreamCollectionId() );
       
   655         newRemoteCand->SetStreamId( localCand->StreamId() );
       
   656         newRemoteCand->SetComponentId( localCand->ComponentId() );
       
   657         newRemoteCand->SetPriority( aPriority );
       
   658         
       
   659         CNATFWCandidate* peerReflCand 
       
   660             = CNATFWCandidate::NewLC( *newRemoteCand );
       
   661         // Session data generates arbitrary foundation
       
   662         iSessionData.AddPeerReflexiveCandidateL( peerReflCand, ETrue );
       
   663         CleanupStack::Pop( peerReflCand );
       
   664         }
       
   665     
       
   666     CNATFWCandidatePair* pair = CNATFWCandidatePair::NewLC( 
       
   667         *localCand, *newRemoteCand );
       
   668     pair->SetSelected( aRemoteFavored );
       
   669     HandleTriggeredCheckL( *pair );
       
   670     
       
   671     CleanupStack::PopAndDestroy( pair );
       
   672     CleanupStack::PopAndDestroy( newRemoteCand );
       
   673     }
       
   674 
       
   675 
       
   676 // ---------------------------------------------------------------------------
       
   677 // CIceCheckList::RelayUsedForSelectedPairL
       
   678 // ---------------------------------------------------------------------------
       
   679 //
       
   680 TBool CIceCheckList::RelayUsedForSelectedPairL() const
       
   681     {
       
   682     __ICEDP( "CIceCheckList::RelayUsedForSelectedPairL" )
       
   683 
       
   684     TInt numOfComponents( iComponentIds.Count() );
       
   685     __ASSERT_ALWAYS( numOfComponents, User::Leave( KErrNotReady ) );
       
   686     
       
   687     TBool relayUseDetected( EFalse );
       
   688     for ( TInt i( 0 ); i < numOfComponents; ++i )
       
   689         {
       
   690         const CNATFWCandidatePair* pair 
       
   691             = iValidList->SelectedPair( iComponentIds[i] );
       
   692         
       
   693         if ( !relayUseDetected && pair
       
   694             && CNATFWCandidate::ERelay == pair->LocalCandidate().Type() )
       
   695             {
       
   696             relayUseDetected = ETrue;
       
   697             }
       
   698         }
       
   699     
       
   700     return relayUseDetected;
       
   701     }
       
   702 
       
   703 
       
   704 // ---------------------------------------------------------------------------
       
   705 // CIceCheckList::RecomputePairPriorities
       
   706 // ---------------------------------------------------------------------------
       
   707 //
       
   708 void CIceCheckList::RecomputePairPriorities()
       
   709     {
       
   710     __ICEDP( "CIceCheckList::RecomputePairPriorities" )
       
   711     
       
   712     iCheckPrioritizer->PrioritizeChecks( iChecks, iSessionData.Role() );
       
   713     
       
   714     iChecks.Sort( CIceConnectivityCheck::ComparePriorities );
       
   715     }
       
   716 
       
   717 
       
   718 // Derived function
       
   719 
       
   720 // ---------------------------------------------------------------------------
       
   721 // CIceCheckList::CheckCompletedL
       
   722 // From class MIceConnCheckListener.
       
   723 // Once a successful check has completed for the first component, the other
       
   724 // components of the same type and local preference will get performed.
       
   725 // ---------------------------------------------------------------------------
       
   726 //
       
   727 void CIceCheckList::CheckCompletedL( 
       
   728         TInt aCompletionCode,
       
   729         const CIceConnectivityCheck& aCheck,
       
   730         CNATFWCandidatePair* aValidatedPair )
       
   731     {
       
   732     __ICEDP_INT1( "CIceCheckList::CheckCompletedL, COMPLETION_CODE:", 
       
   733         aCompletionCode )
       
   734     
       
   735     CleanupStack::PushL( aValidatedPair );
       
   736     
       
   737     if ( KErrNone == aCompletionCode )
       
   738         {
       
   739         __ASSERT_DEBUG( aValidatedPair, User::Leave( KErrArgument ) );
       
   740         
       
   741         // Priorities of local and remote candidates of validated pair must
       
   742         // be calculated before coming here.
       
   743         iCheckPrioritizer->PrioritizePair( 
       
   744             *aValidatedPair, iSessionData.Role() );
       
   745         iValidList->AddValidPairL( *aValidatedPair );
       
   746         
       
   747         if ( CNATFWCandidate::EPeerReflexive 
       
   748                 == aValidatedPair->LocalCandidate().Type() )
       
   749             {
       
   750             iSessionData.AddPeerReflexiveCandidateL( 
       
   751                 CNATFWCandidate::NewL( aValidatedPair->LocalCandidate() ),
       
   752                 EFalse );
       
   753             }
       
   754         
       
   755         // Unfreeze other checks having same foundation ICE-17, 7.1.2.2.3
       
   756         InitializeCheckListL( aCheck.CandidatePair().Foundation() );
       
   757         
       
   758         TBool validPairsExistForComponents( 
       
   759             iValidList->HasPairForComponents( iComponentIds ) );
       
   760         if ( validPairsExistForComponents )
       
   761             {
       
   762             // Start checks in other check lists for candidates of same type
       
   763             iClient.ComponentsHaveValidPairsL( *this, 
       
   764                 aCheck.CandidatePair().Foundation() );
       
   765             }
       
   766         
       
   767         if ( ( validPairsExistForComponents ) &&
       
   768              ( EIceRoleControlling == iSessionData.Role() ) &&
       
   769              ( !NominationExecuted() ) )
       
   770             {
       
   771             // stopping criteria is minimal latency; nominate pairs when we
       
   772             // have some valid pair for each component
       
   773             NominateCandidatePairsL();
       
   774             }
       
   775         }
       
   776     else if ( KErrRoleConflict == aCompletionCode )
       
   777         {
       
   778         // ICE-17, section 7.1.2.1. Failure cases.
       
   779         // Candidate pair whose check has generated 487 role conflict is
       
   780         // enqueued to the triggered check queue.
       
   781         TUint priority = PriorityForPeerReflCandL( 
       
   782             aCheck.CandidatePair().LocalCandidate() );
       
   783         
       
   784         EnqueueCheckL( const_cast<CIceConnectivityCheck&>( aCheck ), 
       
   785             CIceConnectivityCheck::EIceCheckTypeTriggered, 
       
   786             priority );
       
   787         
       
   788         TNATFWIceRole currentRole = iSessionData.Role();
       
   789         TNATFWIceRole desiredRole = ( EIceRoleControlling == currentRole )
       
   790             ? EIceRoleControlled : EIceRoleControlling;
       
   791         iClient.RoleChangeNeeded( desiredRole );
       
   792         }
       
   793     else
       
   794         {
       
   795         // unrecoverable failure
       
   796         }
       
   797     
       
   798     CleanupStack::PopAndDestroy( aValidatedPair );
       
   799     
       
   800     DoLosingPairProcessingL( iSelectedPairs );
       
   801     
       
   802     // ICE-17, 7.1.2.3.  Check List and Timer State Updates
       
   803     UpdateCheckListStateL();
       
   804     }
       
   805 
       
   806 
       
   807 // ---------------------------------------------------------------------------
       
   808 // CIceCheckList::NominationCompletedL
       
   809 // From class MIceConnCheckListener.
       
   810 // ICE-15, 7.1.2.2.4.  Updating the Nominated Flag
       
   811 // ---------------------------------------------------------------------------
       
   812 //
       
   813 void CIceCheckList::NominationCompletedL( 
       
   814         TInt aCompletionCode,
       
   815         const CIceConnectivityCheck& /*aCheck*/,
       
   816         const CNATFWCandidatePair& aValidatedPair )
       
   817     {
       
   818     __ICEDP( "CIceCheckList::NominationCompletedL" )
       
   819     
       
   820     if ( KErrNone == aCompletionCode )
       
   821         {
       
   822         iValidList->SetPairNominatedL( aValidatedPair );
       
   823         }
       
   824     
       
   825     // ICE-17, 7.1.2.3.  Check List and Timer State Updates
       
   826     UpdateCheckListStateL();
       
   827     }
       
   828 
       
   829 
       
   830 // ---------------------------------------------------------------------------
       
   831 // CIceCheckList::HandleTriggeredCheckL
       
   832 // ICE-17 7.2.1.4.  Triggered Checks
       
   833 // STUN server has set PRIORITY & USE-CANDIDATE -attributes to the remote
       
   834 // candidate.
       
   835 // ---------------------------------------------------------------------------
       
   836 //
       
   837 void CIceCheckList::HandleTriggeredCheckL( 
       
   838         const CNATFWCandidatePair& aPair )
       
   839     {
       
   840     __ICEDP( "CIceCheckList::HandleTriggeredCheckL" )
       
   841     
       
   842     TUint trCheckPriority 
       
   843         = PriorityForPeerReflCandL( aPair.LocalCandidate() );
       
   844     
       
   845     TInt ind = FindCheck( aPair );
       
   846     
       
   847     if ( KErrNotFound != ind )
       
   848         {
       
   849         // We have corresponding check already in checklist
       
   850         CIceConnectivityCheck& check = *iChecks[ind];
       
   851         check.SetRemoteCheckInfo( 
       
   852             aPair.RemoteCandidate().Priority(), 
       
   853             aPair.Selected() );
       
   854         
       
   855         CIceConnectivityCheck::TIceCheckState state = check.State();
       
   856         if ( CIceConnectivityCheck::EIceCheckWaiting & state 
       
   857             || CIceConnectivityCheck::EIceCheckFrozen & state )
       
   858             {
       
   859             EnqueueCheckL( check, 
       
   860                 CIceConnectivityCheck::EIceCheckTypeTriggered, 
       
   861                 trCheckPriority );
       
   862             }
       
   863         else if ( CIceConnectivityCheck::EIceCheckInProgress & state )
       
   864             {
       
   865             __ICEDP( "CIceCheckList::HandleTriggeredCheckL, INPROGRESS" )
       
   866             // Nomination check should always succeed, so do not cancel it.
       
   867             // With ordinary checks ICE specification is followed.
       
   868             if ( !check.Nominated() )
       
   869                 {
       
   870                 check.Cancel();
       
   871                 EnqueueCheckL( check, 
       
   872                     CIceConnectivityCheck::EIceCheckTypeTriggered,
       
   873                     trCheckPriority );
       
   874                 }
       
   875             }
       
   876         else if ( CIceConnectivityCheck::EIceCheckFailed & state )
       
   877             {
       
   878             EnqueueCheckL( check, 
       
   879                 CIceConnectivityCheck::EIceCheckTypeTriggered,
       
   880                 trCheckPriority );
       
   881             }
       
   882         else if ( CIceConnectivityCheck::EIceCheckSucceed & state )
       
   883             {
       
   884             if ( aPair.Selected() )
       
   885                 {
       
   886                 // ICE-17, 7.2.1.5, Updating the Nominated Flag
       
   887                 const_cast<CNATFWCandidatePair&>
       
   888                     ( check.CandidatePair() ).SetSelected( ETrue );
       
   889                 // Set validated pair learned from this check as selected
       
   890                 const CNATFWCandidatePair* validatedPair 
       
   891                     = check.ValidatedPair();
       
   892                 __ASSERT_DEBUG( NULL != validatedPair, 
       
   893                     User::Leave( KErrNotReady ) );
       
   894                 
       
   895                 iValidList->SetPairNominatedL( *validatedPair );
       
   896                 
       
   897                 UpdateCheckListStateL();
       
   898                 }
       
   899             }
       
   900         else
       
   901             {
       
   902             __ICEDP( "CIceCheckList::HandleTriggeredCheckL, ASSERT" )
       
   903             ASSERT( EFalse );
       
   904             }
       
   905         }
       
   906     else
       
   907         {
       
   908         // We have learned peer reflexive remote candidate
       
   909         CIceConnectivityCheck* trCheck = CIceConnectivityCheck::NewLC(
       
   910             *this, aPair.LocalCandidate(), aPair.RemoteCandidate(), 
       
   911             iConnHandler, iSessionData );
       
   912         iCheckPrioritizer->PrioritizeCheck( *trCheck,
       
   913             iSessionData.Role() );
       
   914         iChecks.InsertInOrderL( trCheck, 
       
   915             CIceConnectivityCheck::ComparePriorities );
       
   916         CleanupStack::Pop( trCheck );
       
   917         
       
   918         // remote priority used due to ICE-17, 7.1.2.2.2
       
   919         trCheck->SetRemoteCheckInfo( 
       
   920             aPair.RemoteCandidate().Priority(), aPair.Selected() );
       
   921         
       
   922         EnqueueCheckL( *trCheck, 
       
   923             CIceConnectivityCheck::EIceCheckTypeTriggered,
       
   924             trCheckPriority );
       
   925         }
       
   926     }
       
   927 
       
   928 
       
   929 // ---------------------------------------------------------------------------
       
   930 // CIceCheckList::UpdateCheckListStateL
       
   931 // Check list state is updated due to check completion or pair nomination.
       
   932 // Refer to ICE-17 7.1.2.3.  Check List and Timer State Updates and
       
   933 // ICE-15 8.2.  Updating States.
       
   934 // Change state to completed if controlling client has selected candidate
       
   935 // pair for every component of the media stream. If all checks for any
       
   936 // media component has failed, ICE processing is stopped for a media stream.
       
   937 // ---------------------------------------------------------------------------
       
   938 //
       
   939 void CIceCheckList::UpdateCheckListStateL()
       
   940     {
       
   941     __ICEDP( "CIceCheckList::UpdateCheckListStateL" )
       
   942     
       
   943     if ( EIceCheckListRunning == State() )
       
   944         {
       
   945         TInt numOfComponents( iComponentIds.Count() );
       
   946         __ASSERT_DEBUG( numOfComponents, User::Leave( KErrNotReady ) );
       
   947         
       
   948         for ( TInt i( 0 ); i < numOfComponents; ++i )
       
   949             {
       
   950             // ICE-15, 8.2. If some component has completed, remove pending
       
   951             // checks for that component.
       
   952             RemovePendingChecks( iComponentIds[i] );
       
   953             }
       
   954         
       
   955         if ( iValidList->NominatedPairsExist( iComponentIds ) )
       
   956             {
       
   957             // when check list completes, frozen check lists are unfreezed
       
   958             SetStateL( EIceCheckListCompleted );
       
   959             }
       
   960         else
       
   961             {
       
   962             // If all checks are completed and there is not valid pair for
       
   963             // each media component, check list has failed. ICE-17, 7.1.2.3.
       
   964             TInt activeStates = (
       
   965                 CIceConnectivityCheck::EIceCheckWaiting |
       
   966                 CIceConnectivityCheck::EIceCheckInProgress |
       
   967                 CIceConnectivityCheck::EIceCheckFrozen );
       
   968             
       
   969             if ( KErrNotFound == FindCheckInState( activeStates )
       
   970                     && !iValidList->HasPairForComponents( iComponentIds ) )
       
   971                 {
       
   972                 // when check list completes, frozen check lists are unfreezed
       
   973                 SetStateL( EIceCheckListFailed );
       
   974                 }
       
   975             }
       
   976         }
       
   977     }
       
   978 
       
   979 
       
   980 // ---------------------------------------------------------------------------
       
   981 // CIceCheckList::RemovePendingChecks
       
   982 // ICE-17, 8.1.2 Updating States
       
   983 // ---------------------------------------------------------------------------
       
   984 //      
       
   985 void CIceCheckList::RemovePendingChecks( TUint aComponentId )
       
   986     {
       
   987     const CNATFWCandidatePair* nominatedPair 
       
   988         = iValidList->SelectedPair( aComponentId );
       
   989     if ( nominatedPair )
       
   990         {
       
   991         TInt stateMask = (
       
   992             CIceConnectivityCheck::EIceCheckWaiting |
       
   993             CIceConnectivityCheck::EIceCheckFrozen );
       
   994         
       
   995         TInt ind = FindCheckInState( stateMask, aComponentId );
       
   996         while ( KErrNotFound != ind )
       
   997             {
       
   998             iChecks.Remove( ind );
       
   999             ind = FindCheckInState( stateMask, aComponentId );
       
  1000             }
       
  1001         }
       
  1002     }
       
  1003 
       
  1004 
       
  1005 // ---------------------------------------------------------------------------
       
  1006 // CIceCheckList::GetComponentIdsL
       
  1007 // ---------------------------------------------------------------------------
       
  1008 //      
       
  1009 void CIceCheckList::GetComponentIdsL( RArray<TUint>& aComponentIds ) const
       
  1010     {
       
  1011     __ICEDP( "CIceCheckList::GetComponentIdsL" )
       
  1012 
       
  1013     aComponentIds.Reset();
       
  1014     TInt count( iChecks.Count() );
       
  1015     for ( TInt i( 0 ); i < count; ++i )
       
  1016         {
       
  1017         TUint curCompId 
       
  1018             = iChecks[i]->CandidatePair().LocalCandidate().ComponentId();
       
  1019         if ( KErrNotFound == aComponentIds.Find( curCompId ) )
       
  1020             {
       
  1021             aComponentIds.AppendL( curCompId );
       
  1022             }
       
  1023         }
       
  1024     }
       
  1025 
       
  1026 
       
  1027 // ---------------------------------------------------------------------------
       
  1028 // CIceCheckList::FindCheckInState
       
  1029 // ---------------------------------------------------------------------------
       
  1030 //
       
  1031 TInt CIceCheckList::FindCheckInState( TInt aStateMask )
       
  1032     {
       
  1033     TInt count( iChecks.Count() );
       
  1034     __ICEDP_INT1( "CIceCheckList::FindCheckInState1:", count )
       
  1035     
       
  1036     for ( TInt i( 0 ); i < count; ++i )
       
  1037         {
       
  1038         CIceConnectivityCheck& check( *iChecks[i] );
       
  1039         if ( aStateMask & check.State() )
       
  1040             {
       
  1041             return i;
       
  1042             }
       
  1043         }
       
  1044     
       
  1045     return KErrNotFound;
       
  1046     }
       
  1047 
       
  1048 
       
  1049 // ---------------------------------------------------------------------------
       
  1050 // CIceCheckList::FindCheckInState
       
  1051 // ---------------------------------------------------------------------------
       
  1052 //
       
  1053 TInt CIceCheckList::FindCheckInState( TInt aStateMask, TUint aComponentId )
       
  1054     {
       
  1055     TInt count( iChecks.Count() );
       
  1056     for ( TInt i( 0 ); i < count; ++i )
       
  1057         {
       
  1058         CIceConnectivityCheck& check( *iChecks[i] );
       
  1059         if ( ( aStateMask & check.State() ) 
       
  1060             && check.ComponentId() == aComponentId )
       
  1061             {
       
  1062             return i;
       
  1063             }
       
  1064         }
       
  1065     
       
  1066     return KErrNotFound;
       
  1067     }
       
  1068 
       
  1069 
       
  1070 // ---------------------------------------------------------------------------
       
  1071 // CIceCheckList::FindCheckInState
       
  1072 // ---------------------------------------------------------------------------
       
  1073 //
       
  1074 TInt CIceCheckList::FindCheckInState( TInt aStateMask, 
       
  1075         const TInetAddr& aRemoteAddr )
       
  1076     {
       
  1077     TInt count( iChecks.Count() );
       
  1078     for ( TInt i( 0 ); i < count; ++i )
       
  1079         {
       
  1080         CIceConnectivityCheck& check( *iChecks[i] );
       
  1081         const TInetAddr& remoteAddr 
       
  1082             = check.CandidatePair().RemoteCandidate().TransportAddr();
       
  1083         if ( ( aStateMask & check.State() ) 
       
  1084             && TIceUtils::MatchAddresses( remoteAddr, aRemoteAddr ) )
       
  1085             {
       
  1086             return i;
       
  1087             }
       
  1088         }
       
  1089     
       
  1090     return KErrNotFound;
       
  1091     }
       
  1092 
       
  1093 
       
  1094 // ---------------------------------------------------------------------------
       
  1095 // CIceCheckList::FindCheck
       
  1096 // ---------------------------------------------------------------------------
       
  1097 //
       
  1098 TInt CIceCheckList::FindCheck( const CNATFWCandidatePair& aPair )
       
  1099     {
       
  1100     for ( TInt i( iChecks.Count() - 1 ); 0 <= i; --i )
       
  1101         {
       
  1102         TBool match = CNATFWCandidatePair::MatchAddresses( 
       
  1103             iChecks[i]->CandidatePair(), aPair );
       
  1104         if ( match )
       
  1105             {
       
  1106             return i;
       
  1107             }
       
  1108         }
       
  1109     
       
  1110     return KErrNotFound;
       
  1111     }
       
  1112 
       
  1113 
       
  1114 // ---------------------------------------------------------------------------
       
  1115 // CIceCheckList::SetStateL
       
  1116 // ---------------------------------------------------------------------------
       
  1117 //
       
  1118 void CIceCheckList::SetStateL( TIceCheckListState aNewState )
       
  1119     {
       
  1120     __ICEDP( "CIceCheckList::SetStateL" )
       
  1121     
       
  1122     __ASSERT_ALWAYS( iState != aNewState, User::Leave( KErrArgument ) );
       
  1123     iState = aNewState;
       
  1124     iCheckQue.Reset();
       
  1125     
       
  1126     if ( EIceCheckListCompleted == aNewState )
       
  1127         {
       
  1128         iTimer->Cancel();
       
  1129         iSelectedPairs.ResetAndDestroy();
       
  1130         
       
  1131         TInt numOfComponents( iComponentIds.Count() );
       
  1132         RPointerArray<CNATFWCandidatePair> selectedPairs;
       
  1133         CleanupResetAndDestroyPushL( selectedPairs );
       
  1134         for ( TInt i( 0 ); i < numOfComponents; ++i )
       
  1135             {
       
  1136             CNATFWCandidatePair* newPair = CNATFWCandidatePair::NewLC(
       
  1137                 *iValidList->SelectedPair( iComponentIds[i] ) );
       
  1138             selectedPairs.AppendL( newPair );
       
  1139             CleanupStack::Pop( newPair );
       
  1140             }
       
  1141         
       
  1142         iClient.ChecklistCompletedL( *this, selectedPairs );
       
  1143         
       
  1144         selectedPairs.Close();
       
  1145         CleanupStack::Pop( &selectedPairs );
       
  1146         }
       
  1147     else if ( EIceCheckListRunning == aNewState )
       
  1148         {
       
  1149         if ( !iTimer->IsActive() )
       
  1150             {
       
  1151             TCallBack callBack( CIceCheckList::TimerFired, this );
       
  1152             iTimer->Start( 0, iInterval, callBack );
       
  1153             }
       
  1154         }
       
  1155     else if ( EIceCheckListFailed == aNewState )
       
  1156         {
       
  1157         iTimer->Cancel();
       
  1158         iSelectedPairs.ResetAndDestroy();
       
  1159         
       
  1160         RArray<TUint> failedStreams;
       
  1161         CleanupClosePushL( failedStreams );
       
  1162         TInt stateMask = (
       
  1163             CIceConnectivityCheck::EIceCheckWaiting |
       
  1164             CIceConnectivityCheck::EIceCheckInProgress |
       
  1165             CIceConnectivityCheck::EIceCheckSucceed | 
       
  1166             CIceConnectivityCheck::EIceCheckFailed |
       
  1167             CIceConnectivityCheck::EIceCheckFrozen );
       
  1168         
       
  1169         TInt numOfComponents( iComponentIds.Count() );
       
  1170         for ( TInt i( 0 ); i < numOfComponents; ++i )
       
  1171             {
       
  1172             if ( KErrNotFound != FindCheckInState( 
       
  1173                     stateMask, iComponentIds[i] ) )
       
  1174                 {
       
  1175                 failedStreams.AppendL( iChecks[i]->StreamId() );
       
  1176                 }
       
  1177             }
       
  1178         
       
  1179         iClient.ChecklistCompletedL( 
       
  1180             *this, failedStreams, KErrCouldNotConnect );
       
  1181         CleanupStack::PopAndDestroy( &failedStreams );
       
  1182         }
       
  1183     else
       
  1184         {
       
  1185         __ICEDP( "CIceCheckList::SetStateL, ELSE" )
       
  1186         User::Leave( KErrArgument );
       
  1187         }
       
  1188     }
       
  1189 
       
  1190 
       
  1191 // ---------------------------------------------------------------------------
       
  1192 // CIceCheckList::DoLosingPairProcessingL
       
  1193 // ICE-17, 9.2.2.3.
       
  1194 // ICE SHOULD be restarted if some peer selected pair has failed.
       
  1195 // ---------------------------------------------------------------------------
       
  1196 //
       
  1197 void CIceCheckList::DoLosingPairProcessingL( 
       
  1198         const RPointerArray<CNATFWCandidatePair>& aSelectedPairs )
       
  1199     {
       
  1200     __ICEDP( "CIceCheckList::DoLosingPairProcessingL" )
       
  1201     
       
  1202     // find out losing pairs
       
  1203     RPointerArray<CNATFWCandidatePair> losingPairs;
       
  1204     CleanupResetAndDestroyPushL( losingPairs );
       
  1205     for ( TInt i( aSelectedPairs.Count() - 1 ); 0 <= i ; --i )
       
  1206         {
       
  1207         const CNATFWCandidatePair& pair( *aSelectedPairs[i] );
       
  1208         if ( iValidList->HasPair( pair ) )
       
  1209             {
       
  1210             iValidList->SetPairNominatedL( pair );
       
  1211             }
       
  1212         else
       
  1213             {
       
  1214             CNATFWCandidatePair* losingPair 
       
  1215                 = CNATFWCandidatePair::NewLC( pair );
       
  1216             losingPairs.AppendL( losingPair );
       
  1217             CleanupStack::Pop( losingPair );
       
  1218             }
       
  1219         }
       
  1220     
       
  1221     /* If none of peer selected pairs is in-progress and at least one
       
  1222        is failed, check list is completed unsuccessfully. If some selected
       
  1223        pair is in-progress, we wait for check completion and do this
       
  1224        processing again. */
       
  1225     TBool inProgressCheckFound( EFalse );
       
  1226     TBool failedCheckFound( EFalse );
       
  1227     TInt losingPairInd( losingPairs.Count() - 1 );
       
  1228     while ( ( 0 <= losingPairInd ) && ( !inProgressCheckFound ) )
       
  1229         {
       
  1230         TInetAddr remoteAddr( 
       
  1231             losingPairs[losingPairInd]->RemoteCandidate().TransportAddr() );
       
  1232         
       
  1233         TInt inProgressCheckInd = FindCheckInState( 
       
  1234             CIceConnectivityCheck::EIceCheckInProgress, remoteAddr );
       
  1235         if ( KErrNotFound == inProgressCheckInd )
       
  1236             {
       
  1237             TInt failedCheckInd = FindCheckInState( 
       
  1238                 CIceConnectivityCheck::EIceCheckFailed, remoteAddr );
       
  1239             if ( KErrNotFound != failedCheckInd )
       
  1240                 {
       
  1241                 failedCheckFound = ETrue;
       
  1242                 }
       
  1243             }
       
  1244         else
       
  1245             {
       
  1246             inProgressCheckFound = ETrue;
       
  1247             }
       
  1248         
       
  1249         losingPairInd--;
       
  1250         }
       
  1251     
       
  1252     if ( failedCheckFound )
       
  1253         {
       
  1254         SetStateL( EIceCheckListFailed );
       
  1255         }
       
  1256     
       
  1257     CleanupStack::PopAndDestroy( &losingPairs );
       
  1258     }
       
  1259 
       
  1260 
       
  1261 // ---------------------------------------------------------------------------
       
  1262 // CIceCheckList::NominateCandidatePairsL
       
  1263 // Resends connectivity checks to select pair for each media component.
       
  1264 // ICE-17, section 8.1.1.1, regular nomination is used.
       
  1265 // ---------------------------------------------------------------------------
       
  1266 //
       
  1267 void CIceCheckList::NominateCandidatePairsL()
       
  1268     {
       
  1269     __ICEDP( "CIceCheckList::NominateCandidatePairsL" )
       
  1270     
       
  1271     TInt numOfComponents( iComponentIds.Count() );
       
  1272     for ( TInt i( 0 ); i < numOfComponents; ++i )
       
  1273         {
       
  1274         const CNATFWCandidatePair* pair 
       
  1275             = iValidList->HighestPriorityPair( iComponentIds[i] );
       
  1276         ASSERT( NULL != pair );
       
  1277         const TInetAddr& lAddr( pair->LocalCandidate().TransportAddr() );
       
  1278         const TInetAddr& rAddr( pair->RemoteCandidate().TransportAddr() );
       
  1279         
       
  1280         TInt index( iChecks.Count() );
       
  1281         TBool checkFound( EFalse );
       
  1282         while ( !checkFound && --index >= 0 )
       
  1283             {
       
  1284             const CNATFWCandidatePair* validatedPair 
       
  1285                 = iChecks[index]->ValidatedPair();
       
  1286             if ( validatedPair )
       
  1287                 {
       
  1288                 const TInetAddr& lAddrOfCheck 
       
  1289                     = validatedPair->LocalCandidate().TransportAddr();
       
  1290                 const TInetAddr& rAddrOfCheck 
       
  1291                     = validatedPair->RemoteCandidate().TransportAddr();
       
  1292                 
       
  1293                 checkFound = 
       
  1294                     ( TIceUtils::MatchAddresses( lAddrOfCheck, lAddr ) &&
       
  1295                       TIceUtils::MatchAddresses( rAddrOfCheck, rAddr ) );
       
  1296                 }
       
  1297             }
       
  1298         
       
  1299         User::LeaveIfError( index );
       
  1300         EnqueueCheckL( *iChecks[index],
       
  1301             CIceConnectivityCheck::EIceCheckTypeNomination, 0 );
       
  1302         }
       
  1303     }
       
  1304 
       
  1305 
       
  1306 // ---------------------------------------------------------------------------
       
  1307 // CIceCheckList::CheckListFrozen
       
  1308 // ---------------------------------------------------------------------------
       
  1309 //
       
  1310 TBool CIceCheckList::CheckListFrozen()
       
  1311     {
       
  1312     __ICEDP( "CIceCheckList::CheckListFrozen" )
       
  1313     
       
  1314     TInt ind( iChecks.Count() );
       
  1315     while ( ind-- )
       
  1316         {
       
  1317         if ( CIceConnectivityCheck::EIceCheckFrozen != iChecks[ind]->State() )
       
  1318             {
       
  1319             return EFalse;
       
  1320             }
       
  1321         }
       
  1322     
       
  1323     return ETrue;
       
  1324     }
       
  1325 
       
  1326 
       
  1327 // ---------------------------------------------------------------------------
       
  1328 // CIceCheckList::EnqueueCheckL
       
  1329 // ---------------------------------------------------------------------------
       
  1330 //
       
  1331 void CIceCheckList::EnqueueCheckL( CIceConnectivityCheck& aCheck,
       
  1332         CIceConnectivityCheck::TIceCheckType aType,
       
  1333         TUint aLocalPriority )
       
  1334     {
       
  1335     TIceCheckQueItem item( aCheck, aType, aLocalPriority );
       
  1336     
       
  1337     TInt index = iCheckQue.Find( item, TIceCheckQueItem::MatchCheck );
       
  1338     if ( CIceConnectivityCheck::EIceCheckTypeNomination == aType 
       
  1339             && KErrNotFound != index )
       
  1340         {
       
  1341         // nomination check is privileged over triggered one
       
  1342         __ICEDP( "CIceCheckList::EnqueueCheckL, REMOVE TRIGGERED CHECK" )
       
  1343         iCheckQue.Remove( index );
       
  1344         }
       
  1345     
       
  1346     // do not allow duplicate entries
       
  1347     if ( KErrNotFound == iCheckQue.Find( 
       
  1348             item, TIceCheckQueItem::MatchCheck ) )
       
  1349         {
       
  1350         __ICEDP( "CIceCheckList::EnqueueCheckL, APPENDING" )
       
  1351         iCheckQue.AppendL( item );
       
  1352         
       
  1353         if ( !iTimer->IsActive() )
       
  1354             {
       
  1355             TCallBack callBack( CIceCheckList::TimerFired, this );
       
  1356             iTimer->Start( 0, iInterval, callBack );
       
  1357             }
       
  1358         }
       
  1359     else
       
  1360         {
       
  1361         __ICEDP( "CIceCheckList::EnqueueCheckL, DUPLICATE ENTRY" )
       
  1362         }
       
  1363     }
       
  1364 
       
  1365 
       
  1366 // ---------------------------------------------------------------------------
       
  1367 // CIceCheckList::DequeueCheckL
       
  1368 // ---------------------------------------------------------------------------
       
  1369 //
       
  1370 TBool CIceCheckList::DequeueCheckL()
       
  1371     {
       
  1372     __ICEDP_INT1( "CIceCheckList::DequeueCheckL, COUNT:", iCheckQue.Count() )
       
  1373     
       
  1374     if ( 0 != iCheckQue.Count() )
       
  1375         {
       
  1376         TIceCheckQueItem item = iCheckQue[0];
       
  1377         iCheckQue.Remove( 0 );
       
  1378         
       
  1379         CIceConnectivityCheck& check = item.Check();
       
  1380         if ( CIceConnectivityCheck::EIceCheckTypeNomination == item.Type() )
       
  1381             {
       
  1382             check.PerformNominationL( RetransmissionTimeOut() );
       
  1383             }
       
  1384         else
       
  1385             {
       
  1386             CIceConnectivityCheck::TIceCheckState state = check.State();
       
  1387             // save bandwidth if previous transaction already succeeded
       
  1388             if ( CIceConnectivityCheck::EIceCheckSucceed != state )
       
  1389                 {
       
  1390                 check.Initialize();
       
  1391                 check.PerformConnCheckL(
       
  1392                     CIceConnectivityCheck::EIceCheckTypeTriggered,
       
  1393                     item.Priority(), RetransmissionTimeOut() );
       
  1394                 }
       
  1395             }
       
  1396         
       
  1397         return ETrue;
       
  1398         }
       
  1399     else
       
  1400         {
       
  1401         return EFalse;
       
  1402         }
       
  1403     }
       
  1404 
       
  1405 
       
  1406 // ---------------------------------------------------------------------------
       
  1407 // CIceCheckList::RetransmissionTimeOut
       
  1408 // ICE-17, section 16. RTO = MAX (100ms, Ta*N * (Num-Waiting))
       
  1409 // ---------------------------------------------------------------------------
       
  1410 //
       
  1411 TUint CIceCheckList::RetransmissionTimeOut() const
       
  1412     {
       
  1413     TInt numOfWaitingPairs( 0 );
       
  1414     
       
  1415     TInt numOfChecks( iChecks.Count() );
       
  1416     for ( TInt i( 0 ); i < numOfChecks; ++i )
       
  1417         {
       
  1418         CIceConnectivityCheck& check( *iChecks[i] );
       
  1419         if ( CIceConnectivityCheck::EIceCheckWaiting == check.State() )
       
  1420             {
       
  1421             numOfWaitingPairs++;
       
  1422             }
       
  1423         }
       
  1424     
       
  1425     const TInt KMinimumRto( 100 );
       
  1426     return TUint( Max( KMinimumRto, iInterval.Int() * numOfWaitingPairs ) );
       
  1427     }
       
  1428 
       
  1429 
       
  1430 // ---------------------------------------------------------------------------
       
  1431 // CIceCheckList::FoundationsForCollectionL
       
  1432 // ---------------------------------------------------------------------------
       
  1433 //
       
  1434 CDesC8ArrayFlat* CIceCheckList::FoundationsForCollectionL( 
       
  1435         TUint aStreamCollectionId ) const
       
  1436     {
       
  1437     const TInt KGranularity(4);
       
  1438     CDesC8ArrayFlat* descArray = new (ELeave) CDesC8ArrayFlat( KGranularity );
       
  1439     CleanupStack::PushL( descArray );
       
  1440     
       
  1441     TInt numOfChecks( iChecks.Count() );
       
  1442     for ( TInt i(0); i < numOfChecks; ++i )
       
  1443         {
       
  1444         CIceConnectivityCheck& check( *iChecks[i] );
       
  1445         if ( check.StreamCollectionId() == aStreamCollectionId )
       
  1446             {
       
  1447             TInt matchItemInd(0);
       
  1448             const TDesC8& foundation( 
       
  1449                 iChecks[i]->CandidatePair().Foundation() );
       
  1450             if ( 0 != descArray->Find( foundation, matchItemInd ) )
       
  1451                 {
       
  1452                 descArray->AppendL( foundation );
       
  1453                 }
       
  1454             }
       
  1455         }
       
  1456     
       
  1457     CleanupStack::Pop( descArray );
       
  1458     return descArray;
       
  1459     }
       
  1460 
       
  1461 
       
  1462 // ---------------------------------------------------------------------------
       
  1463 // CIceCheckList::LowestComponentId
       
  1464 // ---------------------------------------------------------------------------
       
  1465 //
       
  1466 TUint CIceCheckList::LowestComponentId( RArray<TUint>& aComponentIds ) const
       
  1467     {
       
  1468     TInt componentIdCount( aComponentIds.Count() );
       
  1469     ASSERT( 0 != componentIdCount );
       
  1470     
       
  1471     TUint lowestComponentId( aComponentIds[0] );
       
  1472     for ( TInt i(1); i < componentIdCount; ++i )
       
  1473         {
       
  1474         if ( aComponentIds[i] < lowestComponentId )
       
  1475             {
       
  1476             lowestComponentId = aComponentIds[i];
       
  1477             }
       
  1478         }
       
  1479     
       
  1480     return lowestComponentId;
       
  1481     }
       
  1482 
       
  1483 
       
  1484 // ---------------------------------------------------------------------------
       
  1485 // CIceCheckList::NominationExecuted
       
  1486 // ---------------------------------------------------------------------------
       
  1487 //
       
  1488 TBool CIceCheckList::NominationExecuted() const
       
  1489     {
       
  1490     TInt numOfChecks( iChecks.Count() );
       
  1491     for ( TInt i(0); i < numOfChecks; ++i )
       
  1492         {
       
  1493         CIceConnectivityCheck& check( *iChecks[i] );
       
  1494         if ( check.Nominated() )
       
  1495             {
       
  1496             return ETrue;
       
  1497             }
       
  1498         }
       
  1499     
       
  1500     return EFalse;
       
  1501     }
       
  1502 
       
  1503 
       
  1504 // ---------------------------------------------------------------------------
       
  1505 // CIceCheckList::InitializeCheckList
       
  1506 // Special initialization due to ICE-17, 9.3.1.4 ICE Continuing for Existing
       
  1507 // Media Stream.
       
  1508 // ---------------------------------------------------------------------------
       
  1509 //
       
  1510 void CIceCheckList::InitializeCheckList( const TDesC8& aFoundation, 
       
  1511         TInt aExcludedComponentId )
       
  1512     {
       
  1513     __ICEDP( "CIceCheckList::InitializeCheckList" )
       
  1514     ASSERT( 0 != iChecks.Count() );
       
  1515     
       
  1516     for ( TInt i( iChecks.Count() - 1 ); i >= 0; --i )
       
  1517         {
       
  1518         if ( CIceConnectivityCheck::EIceCheckFrozen == iChecks[i]->State()
       
  1519                 && iChecks[i]->CandidatePair().Foundation() == aFoundation
       
  1520                 && iChecks[i]->ComponentId() != aExcludedComponentId )
       
  1521             {
       
  1522             iChecks[i]->Initialize();
       
  1523             }
       
  1524         }
       
  1525     }