natfw/natfwicecandidatehandler/src/cicelocalcandidatefinder.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2006-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 <ecom/ecom.h>
       
    22 #include "natfwpluginapi.h"
       
    23 #include "natfwcandidate.h"
       
    24 #include "cicelocalcandidatefinder.h"
       
    25 #include "cicesessiondata.h"
       
    26 #include "cicecandidateprioritizer.h"
       
    27 #include "ticenatplugincontaineriter.h"
       
    28 #include "icecandidatehandlerlogs.h"
       
    29 #include "cicehostresolver.h"
       
    30 
       
    31 const TInt KMsToUsFactor = 1000;
       
    32 
       
    33 // ======== MEMBER FUNCTIONS ========
       
    34 
       
    35 // ---------------------------------------------------------------------------
       
    36 // CIceLocalCandidateFinder::CIceLocalCandidateFinder
       
    37 // ---------------------------------------------------------------------------
       
    38 //
       
    39 CIceLocalCandidateFinder::CIceLocalCandidateFinder(
       
    40         MIceNatPluginEventObs& aEventObserver,
       
    41         CIceSessionData& aSessionData,
       
    42         CIceNatPluginContainer& aPluginContainer )
       
    43     :
       
    44     iEventObserver( aEventObserver ),
       
    45     iSessionData( aSessionData ),
       
    46     iPluginContainer( aPluginContainer )
       
    47     {
       
    48     __ICEDP( "CIceLocalCandidateFinder::CIceLocalCandidateFinder" )
       
    49     }
       
    50     
       
    51 // ---------------------------------------------------------------------------
       
    52 // Symbian constructor
       
    53 // ---------------------------------------------------------------------------
       
    54 //
       
    55 void CIceLocalCandidateFinder::ConstructL()
       
    56     {
       
    57     __ICEDP( "CIceLocalCandidateFinder::ConstructL" )
       
    58     
       
    59     iPrioritizer = CIceCandidatePrioritizer::NewL( iSessionData.Domain() );
       
    60     iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
    61     
       
    62     iPluginContainer.RegObserverForEventL( *this, 
       
    63         MIceNatPluginEventObs::ELocalCandidateFound );
       
    64     iPluginContainer.RegObserverForEventL( *this, 
       
    65         MIceNatPluginEventObs::EFetchingCompleted );
       
    66     }
       
    67     
       
    68 
       
    69 // ---------------------------------------------------------------------------
       
    70 // Symbian constructor
       
    71 // ---------------------------------------------------------------------------
       
    72 //
       
    73 CIceLocalCandidateFinder* CIceLocalCandidateFinder::NewL(
       
    74         MIceNatPluginEventObs& aEventObserver,
       
    75         CIceSessionData& aSessionData,
       
    76         CIceNatPluginContainer& aPluginContainer )
       
    77     {
       
    78     __ICEDP( "CIceLocalCandidateFinder::NewL" )
       
    79     
       
    80     CIceLocalCandidateFinder* self = CIceLocalCandidateFinder::NewLC(
       
    81         aEventObserver, aSessionData, aPluginContainer );
       
    82     CleanupStack::Pop( self );
       
    83     return self;
       
    84     }
       
    85 
       
    86 
       
    87 // ---------------------------------------------------------------------------
       
    88 // Symbian constructor
       
    89 // ---------------------------------------------------------------------------
       
    90 //
       
    91 CIceLocalCandidateFinder* CIceLocalCandidateFinder::NewLC(
       
    92         MIceNatPluginEventObs& aEventObserver,
       
    93         CIceSessionData& aSessionData,
       
    94         CIceNatPluginContainer& aPluginContainer )
       
    95     {
       
    96     __ICEDP( "CIceLocalCandidateFinder::NewLC" )
       
    97 
       
    98     CIceLocalCandidateFinder* self = new( ELeave ) 
       
    99         CIceLocalCandidateFinder( 
       
   100         aEventObserver, aSessionData, aPluginContainer );
       
   101     CleanupStack::PushL( self );
       
   102     self->ConstructL();
       
   103 
       
   104     return self;
       
   105     }
       
   106 
       
   107 
       
   108 // ---------------------------------------------------------------------------
       
   109 // destructor
       
   110 // ---------------------------------------------------------------------------
       
   111 //
       
   112 CIceLocalCandidateFinder::~CIceLocalCandidateFinder()
       
   113     {
       
   114     __ICEDP( "CIceLocalCandidateFinder::~CIceLocalCandidateFinder" )
       
   115     
       
   116     delete iPrioritizer;
       
   117     delete iTimer;
       
   118     iResolveRequests.Close();
       
   119     iResolvingCnts.Close();
       
   120     
       
   121     iPluginContainer.UnregObserver( *this );
       
   122     }
       
   123 
       
   124 
       
   125 // ---------------------------------------------------------------------------
       
   126 // CIceLocalCandidateFinder::ResolveNextCandidate
       
   127 // ---------------------------------------------------------------------------
       
   128 //
       
   129 TInt CIceLocalCandidateFinder::ResolveNextCandidate( TAny* aObject )
       
   130     {
       
   131     if ( aObject )
       
   132         {
       
   133         TRAP_IGNORE( 
       
   134             reinterpret_cast<CIceLocalCandidateFinder*>( aObject )
       
   135             ->ResolveNextCandidateL() )
       
   136         return 1;
       
   137         }
       
   138     else
       
   139         {
       
   140         return 0;
       
   141         }
       
   142     }
       
   143 
       
   144 
       
   145 // ---------------------------------------------------------------------------
       
   146 // CIceLocalCandidateFinder::FetchCandidatesL
       
   147 // ---------------------------------------------------------------------------
       
   148 //
       
   149 void CIceLocalCandidateFinder::FetchCandidatesL( 
       
   150         TUint aStreamCollectionId, TUint aStreamId, TUint aComponentId,
       
   151         TUint aAddrFamily, TBool aIPv6After )
       
   152     {
       
   153     __ICEDP( "CIceLocalCandidateFinder::FetchCandidatesL" )
       
   154     
       
   155     TInt numOfRequests = iPluginContainer.Count();
       
   156     TCounter counter( aStreamId, numOfRequests );
       
   157     __ASSERT_ALWAYS( KErrNotFound == iResolvingCnts.Find( 
       
   158         counter, TCounter::MatchStreamId ), 
       
   159         User::Leave( KErrAlreadyExists ) );
       
   160     iResolvingCnts.AppendL( counter );
       
   161     
       
   162     // form requests
       
   163     TIceNatPluginContainerIter iterator 
       
   164         = TIceNatPluginContainerIter( iPluginContainer );
       
   165     while ( !iterator.IsDone() )
       
   166         {
       
   167         CNATFWPluginApi* item = iterator++;
       
   168 
       
   169         ScheduleResolveRequestL( *item, aStreamCollectionId, aStreamId, 
       
   170             aComponentId, aAddrFamily, aIPv6After );
       
   171         }
       
   172     }
       
   173 
       
   174 
       
   175 // ---------------------------------------------------------------------------
       
   176 // From class MIceNatPluginEventObs.
       
   177 // CIceLocalCandidateFinder::PluginEventOccured
       
   178 // ---------------------------------------------------------------------------
       
   179 //
       
   180 void CIceLocalCandidateFinder::PluginEventOccured( 
       
   181         const CNATFWPluginApi* aPlugin, TUint aStreamId, 
       
   182         MIceNatPluginEventObs::TNatPluginEvent aEventCode, 
       
   183         TInt aErrorCode, TAny* aEventData, TUint aStreamConnectionId,
       
   184         TUint aComponentId, TBool aIPv6After )
       
   185     {
       
   186     __ICEDP( "CIceLocalCandidateFinder::PluginEventOccured" )
       
   187     
       
   188     switch ( aEventCode )
       
   189         {
       
   190         case MIceNatPluginEventObs::ELocalCandidateFound:
       
   191             {
       
   192             if ( aEventData && NULL != aPlugin )
       
   193                 {
       
   194                 CNATFWCandidate* candidate 
       
   195                     = reinterpret_cast<CNATFWCandidate*>( aEventData );
       
   196                 NewLocalCandidateFound( *aPlugin, *candidate );
       
   197                 }
       
   198             else
       
   199                 {
       
   200                 __ICEDP( "CIceLocalCandidateFinder::PluginEventOccured, ELSE" )
       
   201                 ASSERT( EFalse );
       
   202                 }
       
   203             }
       
   204             break;
       
   205         
       
   206         case MIceNatPluginEventObs::EFetchingCompleted:
       
   207             {
       
   208             if ( KErrNone == aErrorCode )
       
   209                 {
       
   210                 iSucceeded = ETrue;
       
   211                 }
       
   212 
       
   213             // At least one candidate must success
       
   214             // otherwise pass error code upwards.
       
   215             if ( ResolvingCompleted( aStreamId, aStreamConnectionId,
       
   216                      aComponentId, aIPv6After ) )
       
   217                 {
       
   218                 iSucceeded ? aErrorCode = KErrNone : aErrorCode = KErrNotFound;
       
   219                 iSucceeded = EFalse;
       
   220 
       
   221                 iEventObserver.PluginEventOccured( NULL, aStreamId,
       
   222                      aEventCode, aErrorCode, aEventData, aStreamConnectionId,
       
   223                      aComponentId, aIPv6After );
       
   224                 }
       
   225             }
       
   226             break;
       
   227 
       
   228         default:
       
   229             __ICEDP( "CIceLocalCandidateFinder::PluginEventOccured, DEFAULT" )
       
   230             ASSERT( EFalse );
       
   231         }
       
   232     }
       
   233 
       
   234 
       
   235 // ---------------------------------------------------------------------------
       
   236 // CIceLocalCandidateFinder::ScheduleResolveRequestL
       
   237 // ---------------------------------------------------------------------------
       
   238 //
       
   239 void CIceLocalCandidateFinder::ScheduleResolveRequestL( 
       
   240         const CNATFWPluginApi& aPlugin,
       
   241         TUint aCollectionId, TUint aStreamId, TUint aComponentId,
       
   242         TUint aAddrFamily, TBool aIPv6After )
       
   243     {
       
   244     __ICEDP( "CIceLocalCandidateFinder::ScheduleResolveRequestL" )
       
   245     
       
   246     TResolveRequest request( aPlugin,
       
   247         aCollectionId, aStreamId, aComponentId, 
       
   248         TResolveRequest::ERequestNotIssued, aAddrFamily, aIPv6After );
       
   249     iResolveRequests.AppendL( request );
       
   250     
       
   251     if ( !iTimer->IsActive() )
       
   252         {
       
   253         TCallBack callBack( 
       
   254             CIceLocalCandidateFinder::ResolveNextCandidate, this );
       
   255         iTimer->Start( 
       
   256             0, iSessionData.TaTimerValue() * KMsToUsFactor, callBack );
       
   257         }
       
   258     }
       
   259 
       
   260 
       
   261 // ---------------------------------------------------------------------------
       
   262 // CIceLocalCandidateFinder::ResolveNextCandidateL
       
   263 // ---------------------------------------------------------------------------
       
   264 //
       
   265 void CIceLocalCandidateFinder::ResolveNextCandidateL()
       
   266     {
       
   267     TResolveRequest searchItem( TResolveRequest::ERequestNotIssued );
       
   268     TInt reqIndex = iResolveRequests.Find( 
       
   269         searchItem, TResolveRequest::MatchState );
       
   270     
       
   271     if ( KErrNotFound != reqIndex )
       
   272         {
       
   273         __ICEDP( "CIceLocalCandidateFinder::ResolveNextCandidateL" )
       
   274         
       
   275         TResolveRequest& request( iResolveRequests[reqIndex] );
       
   276         request.SetState( TResolveRequest::ERequestOngoing );
       
   277         
       
   278         CNATFWPluginApi* plugin
       
   279             = const_cast<CNATFWPluginApi*>( request.Plugin() );
       
   280         ASSERT( NULL != plugin );
       
   281         
       
   282         TInt error( KErrNone );
       
   283         if ( KNatPluginIdNokiaHost() == plugin->PluginIdentifier() )
       
   284             {
       
   285             // Create connection with desired address family
       
   286             TUint addrFamily( request.AddrFamily() );
       
   287             TRAP( error, plugin->FetchCandidateL( request.StreamId(),
       
   288                 RetransmissionTimeOut(), addrFamily ) );
       
   289             if ( KErrNone != error )
       
   290                 {
       
   291                 PluginEventOccured( plugin, request.StreamId(), 
       
   292                     MIceNatPluginEventObs::EFetchingCompleted, error, NULL );
       
   293                 }
       
   294             else
       
   295                 {
       
   296                 CIceHostResolver* host
       
   297                     = reinterpret_cast<CIceHostResolver*>( plugin );
       
   298                 iLocalAddr = host->LocalAddress( 
       
   299                     request.StreamId(), addrFamily );
       
   300                 ASSERT( !iLocalAddr.IsUnspecified() );
       
   301                 }
       
   302             }
       
   303         else
       
   304             {
       
   305             TRAP( error, plugin->FetchCandidateL( request.StreamId(), 
       
   306                 RetransmissionTimeOut(), iLocalAddr ) );
       
   307             if ( KErrNone != error )
       
   308                 {
       
   309                 PluginEventOccured( plugin, request.StreamId(), 
       
   310                     MIceNatPluginEventObs::EFetchingCompleted, error, NULL );
       
   311                 }
       
   312             }
       
   313         }
       
   314     else
       
   315         {
       
   316         __ICEDP( "CIceLocalCandidateFinder::ResolveNextCandidateL, READY" )
       
   317         
       
   318         iTimer->Cancel();
       
   319         }
       
   320     }
       
   321 
       
   322 
       
   323 // ---------------------------------------------------------------------------
       
   324 // CIceLocalCandidateFinder::NewLocalCandidateFound
       
   325 // ---------------------------------------------------------------------------
       
   326 //
       
   327 void CIceLocalCandidateFinder::NewLocalCandidateFound( 
       
   328         const CNATFWPluginApi& aPlugin,
       
   329         CNATFWCandidate& aLocalCandidate )
       
   330     {
       
   331     __ICEDP("CIceLocalCandidateFinder::NewLocalCandidateFound")
       
   332 
       
   333     TResolveRequest searchItem( aPlugin, aLocalCandidate.StreamId(), 
       
   334         TResolveRequest::ERequestOngoing );
       
   335     TInt index( iResolveRequests.Find( 
       
   336         searchItem, TResolveRequest::MatchStreamStatePlugin ) );
       
   337     
       
   338     if ( KErrNotFound != index )
       
   339         {
       
   340         aLocalCandidate.SetStreamCollectionId( 
       
   341             iResolveRequests[index].CollectionId() );
       
   342         aLocalCandidate.SetComponentId( 
       
   343             iResolveRequests[index].ComponentId() );
       
   344         
       
   345         TRAP_IGNORE( iPrioritizer->PrioritizeL( aLocalCandidate ) )
       
   346         }
       
   347     else
       
   348         {
       
   349         ASSERT( EFalse );
       
   350         }
       
   351     
       
   352     TBool redundantCandidate( EFalse );
       
   353     TInt error( KErrNone );
       
   354     TRAP( error, redundantCandidate 
       
   355         = iSessionData.AddLocalCandidateL( &aLocalCandidate ) )
       
   356     
       
   357     if ( ( !redundantCandidate ) && ( KErrNone == error ) )
       
   358         {
       
   359         iEventObserver.PluginEventOccured( 
       
   360             NULL,
       
   361             aLocalCandidate.StreamId(),
       
   362             MIceNatPluginEventObs::ELocalCandidateFound,
       
   363             KErrNone,
       
   364             CNATFWCandidate::NewL( aLocalCandidate ) );
       
   365         }
       
   366     }
       
   367 
       
   368 
       
   369 // ---------------------------------------------------------------------------
       
   370 // CIceLocalCandidateFinder::ResolvingCompleted
       
   371 // ---------------------------------------------------------------------------
       
   372 //
       
   373 TBool CIceLocalCandidateFinder::ResolvingCompleted( TUint aStreamId,
       
   374         TUint& aStreamCollectionId, TUint& aComponentId, TBool& aIPv6After )
       
   375     {
       
   376     __ICEDP( "CIceLocalCandidateFinder::ResolvingCompleted" )
       
   377     
       
   378     TCounter counter( aStreamId );
       
   379     TInt streamInd = iResolvingCnts.Find( counter, TCounter::MatchStreamId );
       
   380     ASSERT( KErrNotFound != streamInd );
       
   381     
       
   382     --iResolvingCnts[streamInd];
       
   383     
       
   384     TBool completed( iResolvingCnts[streamInd] == 0 );
       
   385     if ( completed )
       
   386         {
       
   387         iResolvingCnts.Remove( streamInd );
       
   388         
       
   389         TResolveRequest request( aStreamId );
       
   390         TInt reqIndex = iResolveRequests.Find( request, 
       
   391             TResolveRequest::MatchStreamId );
       
   392 
       
   393         while ( KErrNotFound != reqIndex )
       
   394             {
       
   395             aIPv6After = iResolveRequests[reqIndex].IPv6After();
       
   396             if ( aIPv6After )
       
   397                 {
       
   398                 aStreamCollectionId
       
   399                     = iResolveRequests[reqIndex].CollectionId();
       
   400                 aComponentId = iResolveRequests[reqIndex].ComponentId();
       
   401                 }
       
   402                 
       
   403             iResolveRequests.Remove( reqIndex );
       
   404             reqIndex = iResolveRequests.Find( request, 
       
   405                 TResolveRequest::MatchStreamId );
       
   406             }
       
   407         }
       
   408     
       
   409     return completed;
       
   410     }
       
   411 
       
   412 
       
   413 // ---------------------------------------------------------------------------
       
   414 // CIceLocalCandidateFinder::RetransmissionTimeOut
       
   415 // Calculates RTO while being in gathering phase as specified in ICE-17, 16.
       
   416 // RTO = MAX (100ms, Ta * (number of pairs)), where the number of pairs
       
   417 // refers to the number of pairs of candidates with STUN or TURN servers.
       
   418 // ---------------------------------------------------------------------------
       
   419 //
       
   420 TUint CIceLocalCandidateFinder::RetransmissionTimeOut() const
       
   421     {
       
   422     // resolving requests for host plugin excluded in formula
       
   423     TInt numOfHostRequests( 0 );
       
   424     
       
   425     TInt numOfRequests( iResolveRequests.Count() );
       
   426     for ( TInt i = 0; i < numOfRequests; i++ )
       
   427         {
       
   428         if ( KNatPluginIdNokiaHost() == 
       
   429             iResolveRequests[i].Plugin()->PluginIdentifier() )
       
   430             {
       
   431             numOfHostRequests++;
       
   432             }
       
   433         }
       
   434     
       
   435     TInt numOfPairs = iResolveRequests.Count() - numOfHostRequests;
       
   436     numOfPairs >= 0 ? numOfPairs = numOfPairs : numOfPairs = 0;
       
   437     
       
   438     const TInt KMinimumRto( 100 );
       
   439     return TUint( Max( KMinimumRto, 
       
   440         iSessionData.TaTimerValue() * numOfPairs ) );
       
   441     }