natfw/natfwturnplugin/src/natfwturnconnectionhandler.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2006 - 2008 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:    Creates connection to Connection Multiplexer and TURN client.
       
    15 *                Handles connection specific issues and receives notifications
       
    16 *                through implemented observers. Sends notifications to NAT FW
       
    17 *                Client through NAT Protocol Plug-in observer.
       
    18 *
       
    19 */
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 #include "mncmconnectionmultiplexer.h"
       
    25 #include <cnatfwsettingsapi.h>
       
    26 #include <mnatfwserversettings.h>
       
    27 #include "natfwcandidate.h"
       
    28 #include "mnatfwpluginobserver.h"
       
    29 #include "natfwstunrelaybinding.h"
       
    30 #include "natfwstunclient.h"
       
    31 #include <mnatfwturnsettings.h>
       
    32 
       
    33 #include "natfwturnconnectionhandler.h"
       
    34 #include "natfwturnpluginlogs.h"
       
    35 #include "natfwturnrefreshtimer.h"
       
    36 #include "natfwturnstreamdata.h"
       
    37 #include "natfwturnactivedestinationtimer.h"
       
    38 #include "cturnasynccallback.h"
       
    39 #include "cnatfwturnserversettings.h"
       
    40 
       
    41 #include "natfwunsafmessage.h"
       
    42 #include "natfwunsafmessagefactory.h"
       
    43 #include "natfwunsafremoteaddressattribute.h"
       
    44 #include "natfwunsafdataattribute.h"
       
    45 #include "natfwunsaftcprelaypacket.h"
       
    46 
       
    47 const TUint KDefaultStunSrvPort = 3478;
       
    48 const TUint KDefaultRefreshInterval = 28000000;
       
    49 const TUint KMicrosecFactor = 1000000;
       
    50 const TUint32 KWaitTimeAfterReset = 5000000;
       
    51 // transitioning time changed from 3000000=>0 to get ICE work
       
    52 const TUint32 KDefaultSrvTransitioningTime = 0;
       
    53 const TUint32 KRetryTimeAfter439 = 5000;
       
    54 const TUint KNoBinding = 437;
       
    55 const TUint KServerTransitioning = 439;
       
    56 const TUint KTryAlternate = 300;
       
    57 const TInt KClientSpecificError = -11000;
       
    58 
       
    59 
       
    60 // ======== MEMBER FUNCTIONS ========
       
    61 
       
    62 // ---------------------------------------------------------------------------
       
    63 // C++ default constructor
       
    64 // ---------------------------------------------------------------------------
       
    65 //
       
    66 CNATFWTurnConnectionHandler::CNATFWTurnConnectionHandler(
       
    67     const CNATFWPluginApi& aTurnPlugin )
       
    68     :
       
    69     iTurnPlugin( aTurnPlugin )
       
    70     {
       
    71 
       
    72     }
       
    73 
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // Symbian constructor
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 void CNATFWTurnConnectionHandler::ConstructL(
       
    80     MNATFWPluginObserver& aPluginObserver )
       
    81     {
       
    82     iTimerServ = CDeltaTimer::NewL( CActive::EPriorityStandard );
       
    83     iTurnRefreshTimer = CNATFWTurnRefreshTimer::NewL( *this );
       
    84     iActiveDestinationTimer = CNATFWTurnActiveDestinationTimer::NewL( *this );
       
    85     iAsyncCallback = CTurnAsyncCallback::NewL( iTurnPlugin, aPluginObserver );
       
    86     }
       
    87 
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // Symbian constructor
       
    91 // ---------------------------------------------------------------------------
       
    92 //
       
    93 CNATFWTurnConnectionHandler* CNATFWTurnConnectionHandler::NewL(
       
    94     const CNATFWPluginApi& aTurnPlugin,
       
    95     MNATFWPluginObserver& aPluginObserver )
       
    96     {
       
    97     __TURNPLUGIN( "CNATFWTurnConnectionHandler::NewL" )
       
    98     CNATFWTurnConnectionHandler* self = CNATFWTurnConnectionHandler::NewLC(
       
    99         aTurnPlugin, aPluginObserver );
       
   100     CleanupStack::Pop( self );
       
   101     return self;
       
   102     }
       
   103 
       
   104 
       
   105 // ---------------------------------------------------------------------------
       
   106 // Symbian constructor
       
   107 // ---------------------------------------------------------------------------
       
   108 //
       
   109 CNATFWTurnConnectionHandler* CNATFWTurnConnectionHandler::NewLC(
       
   110     const CNATFWPluginApi& aTurnPlugin,
       
   111     MNATFWPluginObserver& aPluginObserver )
       
   112     {
       
   113     __TURNPLUGIN( "CNATFWTurnConnectionHandler::NewLC" )
       
   114     CNATFWTurnConnectionHandler* self =
       
   115         new( ELeave ) CNATFWTurnConnectionHandler( aTurnPlugin );
       
   116     CleanupStack::PushL( self );
       
   117     self->ConstructL( aPluginObserver );
       
   118     return self;
       
   119     }
       
   120 
       
   121 
       
   122 // ---------------------------------------------------------------------------
       
   123 // Destructor
       
   124 // ---------------------------------------------------------------------------
       
   125 //
       
   126 CNATFWTurnConnectionHandler::~CNATFWTurnConnectionHandler()
       
   127     {
       
   128     __TURNPLUGIN(
       
   129         "CNATFWTurnConnectionHandler::~CNATFWTurnConnectionHandler start" )
       
   130 
       
   131     iServerList.ResetAndDestroy();
       
   132 
       
   133     delete iDomain;
       
   134     delete iNatSettings;
       
   135     delete iTurnRefreshTimer;
       
   136     delete iActiveDestinationTimer;
       
   137 
       
   138     TInt count( iStreamArray.Count() );
       
   139     
       
   140     for ( TInt index = count - 1; index >= 0; index-- )
       
   141         {
       
   142         DeleteStream( index, ETrue );
       
   143         }
       
   144 
       
   145     iStreamArray.Close();
       
   146     delete iStunClient;
       
   147     delete iTimerServ;
       
   148     iConnection.Close();
       
   149     iConnMux = NULL;
       
   150     delete iAsyncCallback;
       
   151 
       
   152     __TURNPLUGIN(
       
   153         "CNATFWTurnConnectionHandler::~CNATFWTurnConnectionHandler end" )
       
   154     }
       
   155 
       
   156 
       
   157 // ---------------------------------------------------------------------------
       
   158 // CNATFWTurnConnectionHandler::PluginInitializeL
       
   159 // ---------------------------------------------------------------------------
       
   160 //
       
   161 void CNATFWTurnConnectionHandler::PluginInitializeL(
       
   162     TUint32 aIapId,
       
   163     const TDesC8& aDomain,
       
   164     MNcmConnectionMultiplexer& aMultiplexer )
       
   165     {
       
   166     __TURNPLUGIN( "CNATFWTurnConnectionHandler::PluginInitializeL start" )
       
   167     iConnMux = &aMultiplexer;
       
   168     delete iDomain;
       
   169     iDomain = NULL;
       
   170     iDomain = aDomain.AllocL();
       
   171     delete iNatSettings;
       
   172     iNatSettings = NULL;
       
   173     iNatSettings = CNATFWNatSettingsApi::NewL( *iDomain );        
       
   174     iNatSettings->RetrieveIapSettingsL( aIapId );
       
   175     iTurnSettings = &iNatSettings->TurnSettingsL();
       
   176     
       
   177     // Generates Server list
       
   178     this->GenerateServerListL();
       
   179     
       
   180     __TURNPLUGIN( "CNATFWTurnConnectionHandler::PluginInitializeL end" )
       
   181     }
       
   182 
       
   183 
       
   184 // ---------------------------------------------------------------------------
       
   185 // CNATFWTurnConnectionHandler::ConnectServerL
       
   186 // ---------------------------------------------------------------------------
       
   187 //
       
   188 void CNATFWTurnConnectionHandler::ConnectServerL(
       
   189     const RSocketServ& aSocketServ,
       
   190     const TName& aConnectionName )
       
   191     {
       
   192     __TURNPLUGIN( "CNATFWTurnConnectionHandler::ConnectServerL start" )
       
   193     
       
   194     iSocketServ = aSocketServ;
       
   195     TName name( aConnectionName );
       
   196     User::LeaveIfError( iConnection.Open( iSocketServ, name ) );
       
   197     this->TryNextServerL();
       
   198     
       
   199     // wait MNATFWStunClientObserver::STUNClientInitCompleted
       
   200     __TURNPLUGIN( "CNATFWTurnConnectionHandler::ConnectServerL end" )
       
   201     }
       
   202 
       
   203 
       
   204 // ---------------------------------------------------------------------------
       
   205 // CNATFWTurnConnectionHandler::FetchCandidateL
       
   206 // ---------------------------------------------------------------------------
       
   207 //
       
   208 void CNATFWTurnConnectionHandler::FetchCandidateL( TUint aStreamId,
       
   209     TUint aRtoValue, TUint aAddrFamily, const TInetAddr& aBaseAddr )
       
   210     {
       
   211     __TURNPLUGIN( "CNATFWTurnConnectionHandler::FetchCandidateL start" )
       
   212     
       
   213     __ASSERT_ALWAYS( iStunClient, User::Leave( KErrNotReady) );
       
   214     __ASSERT_ALWAYS( iStunClient->IsInitialized(), User::Leave(
       
   215         KErrNotReady) );
       
   216     
       
   217     TUint connectionId( aBaseAddr.IsUnspecified() ?
       
   218         iConnMux->CreateConnectionL( aStreamId, aAddrFamily ) :
       
   219         iConnMux->CreateConnectionL( aStreamId, aBaseAddr ) );
       
   220     
       
   221     TConnectionData connData;
       
   222     connData.iConnectionId = connectionId;
       
   223     connData.iServerAddr.SetAddress( iStunClient->STUNServerAddrL().
       
   224         Address() );
       
   225     connData.iServerAddr.SetPort( iStunClient->STUNServerAddrL().Port() );
       
   226     connData.iLocalAddr = iConnMux->LocalIPAddressL( aStreamId,
       
   227         connectionId );
       
   228     
       
   229     TInt index( IndexByStreamId( aStreamId ) );
       
   230     
       
   231     if ( KErrNotFound == index )
       
   232         {
       
   233         TUint32 iapID( 0 );
       
   234         TInt qos( 0 );
       
   235         
       
   236         // The stream is new for the plug-in
       
   237         iConnMux->RegisterConnectionObserverL( aStreamId, *this );
       
   238         iConnMux->RegisterIncomingConnectionObserverL( aStreamId, *this );
       
   239         iConnMux->RegisterOutgoingConnectionObserverL( aStreamId, *this );
       
   240         iConnMux->RegisterMessageObserverL( aStreamId, *this );
       
   241         
       
   242         TStreamData streamData;
       
   243         streamData.iStreamId = aStreamId;
       
   244         iConnMux->GetStreamInfoL( aStreamId, iapID, qos,
       
   245             streamData.iTransportProtocol );
       
   246         streamData.iRtoValue = aRtoValue;
       
   247         streamData.iConnArray.AppendL( connData );
       
   248         CleanupClosePushL( streamData.iConnArray );
       
   249         iStreamArray.AppendL( streamData );
       
   250         CleanupStack::Pop( &streamData.iConnArray );
       
   251         }
       
   252     else
       
   253         {
       
   254         // Store new connection for the existing stream in array
       
   255         iStreamArray[index].iConnArray.AppendL( connData );
       
   256         }
       
   257     
       
   258     // Accept data only from TURN server
       
   259     iConnMux->SetAcceptedFromAddressL( aStreamId, connectionId, 
       
   260         connData.iServerAddr );
       
   261     
       
   262     // Set receiving and sending state active for the created connection
       
   263     iConnMux->SetReceivingStateL( aStreamId, connectionId,
       
   264         EStreamingStateActive );
       
   265     
       
   266     iConnMux->SetSendingStateL( aStreamId, connectionId, connData.iServerAddr,
       
   267         EStreamingStateActive );
       
   268     // wait MNcmConnectionObserver::ConnectionNotify
       
   269     
       
   270     __TURNPLUGIN( "CNATFWTurnConnectionHandler::FetchCandidateL end" )
       
   271     }
       
   272 
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 // CNATFWTurnConnectionHandler::GetConnectionIdL
       
   276 // ---------------------------------------------------------------------------
       
   277 //
       
   278 void CNATFWTurnConnectionHandler::GetConnectionIdL(
       
   279     const CNATFWCandidate& aLocalCandidate,
       
   280     TUint aStreamId,
       
   281     TUint& aConnectionId )
       
   282     {
       
   283     __TURNPLUGIN( "CNATFWTurnConnectionHandler::GetConnectionIdL start" )
       
   284     
       
   285     TInt streamInd( IndexByStreamId( aStreamId ) );
       
   286     TInt connInd( KErrNotFound );
       
   287     TBool connFound( EFalse );
       
   288     
       
   289     if ( KErrNotFound != streamInd )
       
   290         {
       
   291         connInd = iStreamArray[streamInd].iConnArray.Count() - 1;
       
   292         }
       
   293     
       
   294     while ( KErrNotFound != streamInd && !connFound && ( 0 <= connInd ) )
       
   295         {
       
   296         TConnectionData* connection = ConnectionByIndex( streamInd, connInd );
       
   297         
       
   298         if ( CNATFWCandidate::ERelay == aLocalCandidate.Type() &&
       
   299             MatchAddresses( aLocalCandidate.Base(), connection->
       
   300             iLocalCandidate->Base() ) && MatchAddresses( aLocalCandidate.
       
   301             TransportAddr(), connection->iLocalCandidate->TransportAddr() ) )
       
   302             {
       
   303             connFound = ETrue;
       
   304             aConnectionId = connection->iConnectionId;
       
   305             }
       
   306         
       
   307         connInd--;
       
   308         }
       
   309     
       
   310     __ASSERT_ALWAYS( connFound, User::Leave( KErrNotFound ) );
       
   311     
       
   312     __TURNPLUGIN( "CNATFWTurnConnectionHandler::GetConnectionIdL end" )
       
   313     }
       
   314 
       
   315 
       
   316 // ---------------------------------------------------------------------------
       
   317 // CNATFWTurnConnectionHandler::StartTurnRefresh
       
   318 // ---------------------------------------------------------------------------
       
   319 //
       
   320 void CNATFWTurnConnectionHandler::StartTurnRefresh()
       
   321     {
       
   322     __TURNPLUGIN( "CNATFWTurnConnectionHandler::StartTurnRefresh start" )
       
   323     
       
   324     iTurnRefreshStarted = EFalse;
       
   325     iTurnRefreshTimer->StartTurnRefresh( iTurnRefreshInterval );
       
   326     
       
   327     if ( iTurnRefreshTimer->IsRunning() )
       
   328         {
       
   329         iTurnRefreshStarted = ETrue;
       
   330         }
       
   331 
       
   332     __TURNPLUGIN( "CNATFWTurnConnectionHandler::StartTurnRefresh end" )
       
   333     }
       
   334 
       
   335 
       
   336 // ---------------------------------------------------------------------------
       
   337 // CNATFWTurnConnectionHandler::CreateTURNBindingL
       
   338 // ---------------------------------------------------------------------------
       
   339 //
       
   340 void CNATFWTurnConnectionHandler::CreateTURNBindingL( TUint aStreamId,
       
   341                                                       TUint aConnectionId )
       
   342     {
       
   343     __TURNPLUGIN( "CNATFWTurnConnectionHandler::CreateTURNBindingL" )
       
   344     
       
   345     TInt streamInd( IndexByStreamId( aStreamId ) );
       
   346     TConnectionData* connection( NULL );
       
   347     
       
   348     if ( KErrNotFound != streamInd )
       
   349         {
       
   350         connection = ConnectionById( streamInd, aConnectionId );
       
   351         }
       
   352     
       
   353     if ( connection )
       
   354         {
       
   355         CSTUNRelayBinding* turnBinding = CSTUNRelayBinding::NewL(
       
   356             *iStunClient, aStreamId, aConnectionId );
       
   357         
       
   358         CleanupStack::PushL( turnBinding );
       
   359         delete connection->iTurnBinding;
       
   360         connection->iTurnBinding = turnBinding;
       
   361         turnBinding->AllocateRequestL( iStreamArray[streamInd].iRtoValue );
       
   362         CleanupStack::Pop( turnBinding );
       
   363         // wait MStunClientObserver::STUNBindingEventOccurredL
       
   364         }
       
   365     }
       
   366 
       
   367 
       
   368 // ---------------------------------------------------------------------------
       
   369 // CNATFWTurnConnectionHandler::SetReceivingStateL
       
   370 // ---------------------------------------------------------------------------
       
   371 //
       
   372 void CNATFWTurnConnectionHandler::SetReceivingStateL(
       
   373     const CNATFWCandidate& aLocalCandidate,
       
   374     TNATFWStreamingState aState )
       
   375     {
       
   376     __TURNPLUGIN( "CNATFWTurnConnectionHandler::SetReceivingStateL start" )
       
   377     
       
   378     TUint streamId( aLocalCandidate.StreamId() );
       
   379     TUint connId( 0 );
       
   380     TConnectionData* connection = NULL;
       
   381     TRAPD( err, GetConnectionIdL( aLocalCandidate, streamId, connId ) );
       
   382     
       
   383     if ( !err )
       
   384         {
       
   385         TInt streamInd( IndexByStreamId( streamId ) );
       
   386         connection = ConnectionById( streamInd, connId );
       
   387         }
       
   388     
       
   389     if ( connection )
       
   390         {
       
   391         if ( EStreamingStateActive == aState )
       
   392             {
       
   393             if ( connection->iReceivingActivated  )
       
   394                 {
       
   395                 iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
   396                     EActiveReceiving, streamId, KErrNone, NULL );
       
   397                 }
       
   398             else
       
   399                 {
       
   400                 iConnMux->SetReceivingStateL( streamId, connId,
       
   401                     EStreamingStateActive );
       
   402                 }
       
   403             }
       
   404         else
       
   405             {
       
   406             if ( !connection->iReceivingActivated )
       
   407                 {
       
   408                 iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
   409                     EDeactiveReceiving, streamId, KErrNone, NULL );
       
   410                 }
       
   411             else
       
   412                 {
       
   413                 iConnMux->SetReceivingStateL( streamId, connId,
       
   414                     EStreamingStatePassive );
       
   415                 }
       
   416             }
       
   417         }
       
   418     else
       
   419         {
       
   420         if ( EStreamingStateActive == aState )
       
   421             {
       
   422             iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
   423                 EActiveReceiving, streamId, KErrNotFound, NULL );
       
   424             }
       
   425         else
       
   426             {
       
   427             iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
   428                 EDeactiveReceiving, streamId, KErrNotFound, NULL );
       
   429             }
       
   430         }
       
   431     
       
   432     __TURNPLUGIN( "CNATFWTurnConnectionHandler::SetReceivingStateL end" )
       
   433     }
       
   434 
       
   435 
       
   436 // ---------------------------------------------------------------------------
       
   437 // CNATFWTurnConnectionHandler::SetSendingStateL
       
   438 // ---------------------------------------------------------------------------
       
   439 //
       
   440 void CNATFWTurnConnectionHandler::SetSendingStateL(
       
   441     const CNATFWCandidate& aLocalCandidate,
       
   442     TNATFWStreamingState aState,
       
   443     const TInetAddr& aDestAddr )
       
   444     {
       
   445     __TURNPLUGIN_ADDRLOG(
       
   446     "CNATFWTurnConnectionHandler::SetSendingStateL start",
       
   447         aDestAddr )
       
   448     
       
   449     TUint streamId( aLocalCandidate.StreamId() );
       
   450     TUint connId( 0 );
       
   451     TConnectionData* connection = NULL;
       
   452     TInt streamInd( IndexByStreamId( streamId ) );
       
   453     TRAPD( err, GetConnectionIdL( aLocalCandidate, streamId, connId ) );
       
   454     
       
   455     if ( !err )
       
   456         {
       
   457         connection = ConnectionById( streamInd, connId );
       
   458         }
       
   459     
       
   460     if ( connection )
       
   461         {
       
   462         if ( EStreamingStateActive == aState && TConnectionData::
       
   463             EActDestTransitioning == connection->iActDestState )
       
   464             {
       
   465             // Only Active Destination reset (sending passivation)
       
   466             // can be done when in "Transitioning" state.
       
   467             iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
   468                 EActiveSending, streamId, KErrNotReady, NULL );
       
   469             }
       
   470         else
       
   471             {
       
   472             if ( EStreamingStateActive == aState )
       
   473                 {
       
   474                 // Do Set Active Destination Request if the remote
       
   475                 // address differs from current active destination
       
   476                 
       
   477                 if ( !MatchAddresses( connection->iCurrentActDest,
       
   478                     aDestAddr ) )
       
   479                     {
       
   480                     connection->iPeerAddr.SetAddress( aDestAddr.Address() );
       
   481                     connection->iPeerAddr.SetPort( aDestAddr.Port() );
       
   482                     
       
   483                     if ( KProtocolInetTcp == iStreamArray[streamInd].
       
   484                         iTransportProtocol )
       
   485                         {
       
   486                         // We need to do the Connect Request first
       
   487                         // and have successfull response to it.
       
   488                         connection->iTurnBinding->ConnectRequestL(
       
   489                             connection->iPeerAddr );
       
   490                         }
       
   491                     else
       
   492                         {
       
   493                         connection->iTurnBinding
       
   494                             ->SetActiveDestinationRequestL(
       
   495                                 connection->iPeerAddr, 
       
   496                                 connection->iTimerValue );
       
   497                         }
       
   498                     }
       
   499                 else
       
   500                     {
       
   501                     // No need to set this destination active again
       
   502                     iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
   503                         EActiveSending, streamId, KErrNone, NULL );
       
   504                     }
       
   505                 }
       
   506             else
       
   507                 {
       
   508                 // Plug-in's client wants to reset Active Destination.
       
   509                 connection->iPeerAddr = KAFUnspec;
       
   510                 
       
   511                 connection->iTurnBinding->SetActiveDestinationRequestL(
       
   512                     connection->iPeerAddr, connection->iTimerValue );
       
   513                 }
       
   514             }
       
   515         }
       
   516     else
       
   517         {
       
   518         if ( EStreamingStateActive == aState )
       
   519             {
       
   520             iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
   521                 EActiveSending, streamId, KErrNotFound, NULL );
       
   522             }
       
   523         else
       
   524             {
       
   525             iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
   526                 EDeactiveSending, streamId, KErrNotFound, NULL );
       
   527             }
       
   528         }
       
   529     
       
   530     __TURNPLUGIN(
       
   531         "CNATFWTurnConnectionHandler::SetSendingStateL end" )
       
   532     }
       
   533 
       
   534 
       
   535 // ---------------------------------------------------------------------------
       
   536 // CNATFWTurnConnectionHandler::IsRequestOrIndicationL
       
   537 // ---------------------------------------------------------------------------
       
   538 //
       
   539 TBool CNATFWTurnConnectionHandler::IsRequestOrIndicationL(
       
   540     const TDesC8& aMessage ) const
       
   541     {
       
   542     __TURNPLUGIN( "CNATFWTurnConnectionHandler::IsRequestOrIndicationL" )
       
   543 
       
   544     CNATFWUNSAFMessageFactory* decoder = CNATFWUNSAFMessageFactory::NewLC();
       
   545     CNATFWUNSAFMessage* msg = decoder->DecodeL( aMessage );
       
   546     CleanupStack::PopAndDestroy( decoder );
       
   547 
       
   548     if ( CNATFWUNSAFMessage::EAllocateRequest == msg->Type() ||
       
   549          CNATFWUNSAFMessage::EConnectRequest == msg->Type() ||
       
   550          CNATFWUNSAFMessage::ESetActiveDestinationRequest == msg->Type() ||
       
   551          CNATFWUNSAFMessage::ESendIndication == msg->Type() )
       
   552         {
       
   553         delete msg;
       
   554         return ETrue;
       
   555         }
       
   556     else
       
   557         {
       
   558         delete msg;
       
   559         return EFalse;
       
   560         }
       
   561     }
       
   562 
       
   563 
       
   564 // ---------------------------------------------------------------------------
       
   565 // CNATFWTurnConnectionHandler::IsTurnResponseL
       
   566 // ---------------------------------------------------------------------------
       
   567 //
       
   568 TBool CNATFWTurnConnectionHandler::IsTurnResponseL(
       
   569     const TDesC8& aMessage ) const
       
   570     {
       
   571     __TURNPLUGIN( "CNATFWTurnConnectionHandler::IsTurnResponseL" )
       
   572 
       
   573     CNATFWUNSAFMessageFactory* decoder = CNATFWUNSAFMessageFactory::NewLC();
       
   574     CNATFWUNSAFMessage* msg = decoder->DecodeL( aMessage );
       
   575     CleanupStack::PopAndDestroy( decoder );
       
   576 
       
   577     if ( CNATFWUNSAFMessage::EAllocateResponse == msg->Type() ||
       
   578          CNATFWUNSAFMessage::EAllocateErrorResponse == msg->Type() ||
       
   579          CNATFWUNSAFMessage::ESetActiveDestinationResponse == msg->Type() ||
       
   580          CNATFWUNSAFMessage::ESetActiveDestinationErrorResponse ==
       
   581             msg->Type() ||
       
   582          CNATFWUNSAFMessage::EConnectResponse == msg->Type() ||
       
   583          CNATFWUNSAFMessage::EConnectErrorResponse == msg->Type() )
       
   584         {
       
   585         delete msg;
       
   586         return ETrue;
       
   587         }
       
   588     else
       
   589         {
       
   590         delete msg;
       
   591         return EFalse;
       
   592         }
       
   593     }
       
   594 
       
   595 
       
   596 // ---------------------------------------------------------------------------
       
   597 // From base class MStunClientObserver.
       
   598 // CNATFWTurnConnectionHandler::STUNClientInitCompleted
       
   599 // ---------------------------------------------------------------------------
       
   600 //
       
   601 void CNATFWTurnConnectionHandler::STUNClientInitCompleted(
       
   602     const CSTUNClient& /*aClient*/,
       
   603     TInt aCompletionCode )
       
   604     {
       
   605     __TURNPLUGIN(
       
   606         "CNATFWTurnConnectionHandler::STUNClientInitCompleted start" )
       
   607     
       
   608     if ( KErrNone == aCompletionCode )
       
   609         {
       
   610         TRAP_IGNORE( iAsyncCallback->MakeCallbackL(
       
   611             TTurnPluginCallbackInfo::EConnectServer, 0,
       
   612             aCompletionCode, NULL ) )
       
   613         }
       
   614     else
       
   615         {
       
   616         TInt error( KErrNone );
       
   617         TRAP( error, TryNextServerL() );
       
   618         
       
   619         if ( KErrNone != error )
       
   620             {
       
   621             delete iStunClient;
       
   622             iStunClient = NULL;
       
   623             
       
   624             TRAP_IGNORE( iAsyncCallback->MakeCallbackL(
       
   625                 TTurnPluginCallbackInfo::EConnectServer, 0,
       
   626                 ( KClientSpecificError + aCompletionCode), NULL ) )
       
   627             }
       
   628         }
       
   629     
       
   630     __TURNPLUGIN(
       
   631         "CNATFWTurnConnectionHandler::STUNClientInitCompleted end" )
       
   632     }
       
   633 
       
   634 
       
   635 // ---------------------------------------------------------------------------
       
   636 // From base class MStunClientObserver
       
   637 // CNATFWTurnConnectionHandler::STUNBindingEventOccurredL
       
   638 // ---------------------------------------------------------------------------
       
   639 //
       
   640 void CNATFWTurnConnectionHandler::STUNBindingEventOccurredL(
       
   641     TSTUNBindingEvent aEvent,
       
   642     const CBinding& aBinding )
       
   643     {
       
   644     __TURNPLUGIN(
       
   645         "CNATFWTurnConnectionHandler::STUNBindingEventOccurredL start" )
       
   646     
       
   647     const CSTUNRelayBinding& turnBinding =
       
   648         static_cast<const CSTUNRelayBinding&>( aBinding );
       
   649     TUint streamId( turnBinding.StreamId() );
       
   650     TUint connId( turnBinding.ConnectionId() );
       
   651     
       
   652     TInt streamInd( IndexByStreamId( streamId ) );
       
   653     TConnectionData* connection( NULL );
       
   654     
       
   655     if ( KErrNotFound != streamInd )
       
   656         {
       
   657         connection = ConnectionById( streamInd, connId );
       
   658         }
       
   659     
       
   660     if ( connection )
       
   661         {
       
   662         switch ( aEvent )
       
   663             {
       
   664             case EPublicAddressResolved:
       
   665                 {
       
   666                 if ( !connection->iLocalCandidate )
       
   667                     {
       
   668                     if ( iTurnRefreshTimer && !iTurnRefreshStarted )
       
   669                         {
       
   670                         StartTurnRefresh();
       
   671                         }
       
   672                     
       
   673                     TInetAddr relayAddr;
       
   674                     relayAddr.SetAddress( turnBinding.RelayAddr().Address() );
       
   675                     relayAddr.SetPort( turnBinding.RelayAddr().Port() );
       
   676                     
       
   677                     __TURNPLUGIN_ADDRLOG( "CNATFWTurnConnectionHandler::\
       
   678                     STUNBindingEventOccurredL  Adress Resolved ADDRESS: ",
       
   679                         relayAddr )
       
   680                     
       
   681                     CNATFWCandidate* newCandidate = CNATFWCandidate::NewL();
       
   682                     CleanupStack::PushL( newCandidate );
       
   683                     
       
   684                     // Set candidate parameters
       
   685                     newCandidate->SetStreamId( streamId );
       
   686                     newCandidate->SetType( CNATFWCandidate::ERelay );
       
   687                     newCandidate->SetBase( relayAddr );
       
   688                     newCandidate->SetTransportAddrL( relayAddr );
       
   689                     newCandidate->SetTransportProtocol(
       
   690                         iStreamArray[streamInd].iTransportProtocol );
       
   691                     
       
   692                     CNATFWCandidate* copyCandidate = CNATFWCandidate::NewL(
       
   693                         *newCandidate );
       
   694                     connection->iLocalCandidate = copyCandidate;
       
   695                     
       
   696                     iAsyncCallback->MakeCallbackL(
       
   697                         TTurnPluginCallbackInfo::ELocalCandidateFound,
       
   698                             streamId, KErrNone, newCandidate );
       
   699                     
       
   700                     iAsyncCallback->MakeCallbackL(
       
   701                         TTurnPluginCallbackInfo::EFetchingEnd, streamId,
       
   702                             KErrNone, NULL );
       
   703                     
       
   704                     CleanupStack::Pop( newCandidate );
       
   705                     }
       
   706                 }
       
   707                 break;
       
   708             
       
   709             case ECredentialsRejected:
       
   710                 {
       
   711                 __TURNPLUGIN( "CNATFWTurnConnectionHandler::\
       
   712                     STUNBindingEventOccurredL  Credentials Rejected" )
       
   713                 
       
   714                 // TURN server rejected the credentials provided that were
       
   715                 // set with CSTUNClient::SetCredentialsL. Application
       
   716                 // should obtain valid credentials and then use
       
   717                 // CSTUNClient::SetCredentialsL.
       
   718                 iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
   719                     EFetchingEnd, streamId, ( KClientSpecificError +
       
   720                         KErrPermissionDenied ), NULL );
       
   721 
       
   722                 // Remove failed entry from array
       
   723                 DeleteStream( streamInd, ETrue );
       
   724                 }
       
   725                 break;
       
   726             
       
   727             case ETCPConnectOk:
       
   728                 {
       
   729                 __TURNPLUGIN( "CNATFWTurnConnectionHandler::\
       
   730                     STUNBindingEventOccurredL  TCP Connect Ok" )
       
   731                 
       
   732                 // After TCP connect is OK we can set Active Destination.
       
   733                 connection->iTurnBinding->SetActiveDestinationRequestL(
       
   734                     connection->iPeerAddr, connection->iTimerValue );
       
   735                 }
       
   736                 break;
       
   737             
       
   738             // Success
       
   739             case EActiveDestinationSet:
       
   740                 {
       
   741                 __TURNPLUGIN( "CNATFWTurnConnectionHandler::\
       
   742                     STUNBindingEventOccurredL  Active Destination Set" )
       
   743 
       
   744                 if ( TConnectionData::EActDestNoneSet == connection->
       
   745                     iActDestState && !connection->iPeerAddr.IsUnspecified() )
       
   746                     {
       
   747                     if ( connection->iActDestAlreadySetOnServer )
       
   748                         {
       
   749                         // Active Destination was reset on server. Media
       
   750                         // flows in indications while trying to set the
       
   751                         // Active Destination again after 5 seconds.
       
   752                         iAsyncCallback->MakeCallbackL(
       
   753                             TTurnPluginCallbackInfo::EActiveSending,
       
   754                                 iStreamArray[streamInd].iStreamId, KErrNone,
       
   755                                     NULL );
       
   756 
       
   757                         iActiveDestinationTimer->StartTimer(
       
   758                             KWaitTimeAfterReset, iStreamArray[streamInd].
       
   759                                 iStreamId, connection->iConnectionId );
       
   760                         }
       
   761                     else
       
   762                         {
       
   763                         iAsyncCallback->MakeCallbackL(
       
   764                             TTurnPluginCallbackInfo::EActiveSending,
       
   765                                 iStreamArray[streamInd].iStreamId, KErrNone,
       
   766                                     NULL );
       
   767                         
       
   768                         iActiveDestinationTimer->StartTimer(
       
   769                             KDefaultSrvTransitioningTime,
       
   770                                 iStreamArray[streamInd].iStreamId,
       
   771                                     connection->iConnectionId );
       
   772                         
       
   773                         // If a successful response was received, but
       
   774                         // there was a REMOTE-ADDRESS in the request, the
       
   775                         // state machine transitions to the "Set" state
       
   776                         // after three seconds, and the client sets the
       
   777                         // active destination to the value of the REMOTE-
       
   778                         // ADDRESS attribute that was in the request.
       
   779                         }
       
   780                     }
       
   781                 
       
   782                 // else If, while in the "None Set" state, the client
       
   783                 // sent a Set Active Destination request without a
       
   784                 // REMOTE-ADDRESS, and got a successful response,
       
   785                 // there is no change in state.
       
   786                 
       
   787                 else if ( TConnectionData::EActDestSet == connection->
       
   788                     iActDestState )
       
   789                     {
       
   790                     if ( connection->iPeerAddr.IsUnspecified() ||
       
   791                         !MatchAddresses( connection->iPeerAddr, connection->
       
   792                         iCurrentActDest ) )
       
   793                         {
       
   794                         connection->iActDestState = TConnectionData::
       
   795                             EActDestTransitioning;
       
   796                         
       
   797                         // the client enters the "Transitioning" state.
       
   798                         // While in this state, the client MUST NOT send
       
   799                         // a new Set Active Destination request. The value
       
   800                         // of the active destination remains unchanged. In
       
   801                         // addition, the client sets a timer. This timer
       
   802                         // MUST have a value equal to the value of the
       
   803                         // TIMER-VAL attribute from the Set Active
       
   804                         // Destination response.  This is necessary for
       
   805                         // coordinating the state machines between client
       
   806                         // and server.
       
   807                         
       
   808                         iActiveDestinationTimer->StartTimer(
       
   809                             connection->iTimerValue, iStreamArray[streamInd].
       
   810                                 iStreamId, connection->iConnectionId );
       
   811                         }
       
   812                     
       
   813                     // In addition, if, while in the "Set" state, the
       
   814                     // client sends a Set Active Destination request whose
       
   815                     // REMOTE-ADDRESS attribute equals the current active
       
   816                     // destination, and that request generates a success
       
   817                     // response, the client remains in the "Set" state.
       
   818                     }
       
   819                 else
       
   820                     {
       
   821                     // Only Active Destination reset request can be done when
       
   822                     // in "Transitioning" state.
       
   823                     if ( connection->iPeerAddr.IsUnspecified() )
       
   824                         {
       
   825                         iActiveDestinationTimer->StartTimer( connection->
       
   826                             iTimerValue, iStreamArray[streamInd].iStreamId,
       
   827                                 connection->iConnectionId );
       
   828                         }
       
   829                     }
       
   830                 }
       
   831                 break;
       
   832             }
       
   833         }
       
   834 
       
   835     __TURNPLUGIN(
       
   836         "CNATFWTurnConnectionHandler::STUNBindingEventOccurredL end" )
       
   837     }
       
   838 
       
   839 
       
   840 // ---------------------------------------------------------------------------
       
   841 // From base class MStunClientObserver
       
   842 // CNATFWTurnConnectionHandler::STUNBindingErrorOccurred
       
   843 // ---------------------------------------------------------------------------
       
   844 //
       
   845 void CNATFWTurnConnectionHandler::STUNBindingErrorOccurred(
       
   846     const CBinding& aBinding,
       
   847     TInt aError )
       
   848     {
       
   849     __TURNPLUGIN(
       
   850         "CNATFWTurnConnectionHandler::STUNBindingErrorOccurred start" )
       
   851 
       
   852     const CSTUNRelayBinding& turnBinding =
       
   853         static_cast<const CSTUNRelayBinding&>( aBinding );
       
   854     TUint streamId( turnBinding.StreamId() );
       
   855     TUint connId( turnBinding.ConnectionId() );
       
   856     
       
   857     TInt streamInd( IndexByStreamId( streamId ) );
       
   858     TConnectionData* connection( NULL );
       
   859     
       
   860     if ( KErrNotFound != streamInd )
       
   861         {
       
   862         connection = ConnectionById( streamInd, connId );
       
   863         }
       
   864     
       
   865     if ( connection )
       
   866         {
       
   867         if ( KNoBinding == aError && connection->iLocalCandidate )
       
   868             {
       
   869             // A 437 response implies that the allocation has been
       
   870             // removed, and thus the state machine destroyed. A client
       
   871             // MUST NOT send a new Set Active Destination request prior
       
   872             // to the receipt of a response to the previous. The state
       
   873             // machine will further limit the transmission of subsequent
       
   874             // Set Active Destination requests.
       
   875             TRAP_IGNORE( iAsyncCallback->MakeCallbackL(
       
   876                 TTurnPluginCallbackInfo::EActiveSending, streamId,
       
   877                     KErrNotFound, NULL ) )
       
   878 
       
   879             // Remove entry from array as binding does not exist anymore
       
   880             DeleteStream( streamInd, ETrue );
       
   881             }
       
   882         else if ( KServerTransitioning == aError && connection->
       
   883             iLocalCandidate )
       
   884             {
       
   885             if ( TConnectionData::EActDestSet == connection->iActDestState )
       
   886                 {
       
   887                 // When this error is received, the client remains in the
       
   888                 // "Set" state. The client SHOULD retry its Set Active
       
   889                 // Destination request, but no sooner than 500ms after
       
   890                 // receipt of the 439 response.
       
   891                 iActiveDestinationTimer->StartTimer(
       
   892                     KRetryTimeAfter439, iStreamArray[streamInd].iStreamId,
       
   893                         connection->iConnectionId );
       
   894                 }
       
   895             else if ( TConnectionData::EActDestNoneSet == connection->
       
   896                 iActDestState )
       
   897                 {
       
   898                 // Set Active Destination request was received by the
       
   899                 // server over UDP. However, the active destination is
       
   900                 // already set to another value. The client should reset
       
   901                 // the active destination, wait for 5 seconds and set the
       
   902                 // active destination to the new value.
       
   903                 connection->iActDestAlreadySetOnServer = ETrue;
       
   904                 
       
   905                 TRAP_IGNORE( connection->iTurnBinding->
       
   906                     SetActiveDestinationRequestL( KAFUnspec, connection->
       
   907                         iTimerValue ) )
       
   908                 }
       
   909             else
       
   910                 {
       
   911                 // Not possible that this error occurs when in
       
   912                 // "transitioning" state
       
   913                 }
       
   914             }
       
   915         else
       
   916             {
       
   917             if ( !connection->iLocalCandidate )
       
   918                 {
       
   919                 if( KTryAlternate == aError )
       
   920                     {
       
   921                     __TURNPLUGIN( "CNATFWTurnConnectionHandler::\
       
   922                     STUNBindingErrorOccurred  KTryAlternate == aError" )
       
   923                     
       
   924                     connection->iServerAddr.SetAddress( turnBinding.
       
   925                         AlternateServerAddr().Address() );
       
   926                     connection->iServerAddr.SetPort( turnBinding.
       
   927                         AlternateServerAddr().Port() );
       
   928                     
       
   929                     delete connection->iTurnBinding;
       
   930                     connection->iTurnBinding = NULL;
       
   931                     
       
   932                     TRAP_IGNORE( iConnMux->SetSendingStateL( streamId, connId,
       
   933                         connection->iServerAddr, EStreamingStateActive ) )
       
   934                     // wait MNcmConnectionObserver::ConnectionNotify
       
   935                     }
       
   936                 else
       
   937                     {
       
   938                     // If error occurs when trying to fetch candidate
       
   939                     TInt errcode( KClientSpecificError + ( aError ) );
       
   940                     TRAP_IGNORE( iAsyncCallback->MakeCallbackL(
       
   941                         TTurnPluginCallbackInfo::EFetchingEnd, streamId,
       
   942                             errcode, NULL ) )
       
   943                     
       
   944                     // Remove failed entry from array
       
   945                     DeleteStream( streamInd, ETrue );
       
   946                     }
       
   947                 }
       
   948             else
       
   949                 {
       
   950                 // Do nothing if error occurs when doing binding refresh
       
   951                 }
       
   952             }
       
   953         }
       
   954 
       
   955     __TURNPLUGIN(
       
   956         "CNATFWTurnConnectionHandler::STUNBindingErrorOccurred end" )
       
   957     }
       
   958 
       
   959 
       
   960 // ---------------------------------------------------------------------------
       
   961 // from base class MNcmIncomingConnectionObserver
       
   962 // CNATFWTurnConnectionHandler::IncomingMessageL
       
   963 // ---------------------------------------------------------------------------
       
   964 //
       
   965 void CNATFWTurnConnectionHandler::IncomingMessageL(
       
   966     TUint aStreamId,
       
   967     const TDesC8& aMessage,
       
   968     const TInetAddr& /*aLocalAddr*/,
       
   969 #ifdef _DEBUG
       
   970     const TInetAddr& aFromAddr,
       
   971     const TInetAddr& aPeerAddr,
       
   972 #else
       
   973     const TInetAddr& /*aFromAddr*/,
       
   974     const TInetAddr& /*aPeerAddr*/,
       
   975 #endif
       
   976     TBool& aConsumed )
       
   977     {
       
   978     __TURNPLUGIN_ADDRLOG(
       
   979         "CNATFWTurnConnectionHandler::IncomingMessageL FROMADDR", aFromAddr )
       
   980     __TURNPLUGIN_ADDRLOG(
       
   981         "CNATFWTurnConnectionHandler::IncomingMessageL PEERADDR", aPeerAddr )
       
   982     
       
   983     TInetAddr peerAddrFromIndication( KAFUnspec );
       
   984     HBufC8* indicationData( NULL );
       
   985     TInt consumingBindingInd( KErrNotFound );
       
   986     
       
   987     TInt streamInd( IndexByStreamId( aStreamId ) );
       
   988     TInt connInd( KErrNotFound );
       
   989     
       
   990     if ( KErrNotFound != streamInd )
       
   991         {
       
   992         connInd = iStreamArray[streamInd].iConnArray.Count() - 1;
       
   993         }
       
   994     
       
   995     // Offer message for every binding in the stream until consumed
       
   996     while ( KErrNotFound != streamInd && KErrNotFound == consumingBindingInd
       
   997         && ( 0 <= connInd ) )
       
   998         {
       
   999         __TURNPLUGIN( "CNATFWTurnConnectionHandler::IncomingMessageL\
       
  1000         HandleDataL method to be called" )
       
  1001         
       
  1002         TBool consumed( EFalse );
       
  1003         TConnectionData* connection = ConnectionByIndex( streamInd, connInd );
       
  1004         
       
  1005         if ( connection->iTurnBinding )
       
  1006             {
       
  1007             if ( indicationData )
       
  1008                 {
       
  1009                 connection->iTurnBinding->HandleDataL( *indicationData,
       
  1010                     consumed, peerAddrFromIndication );
       
  1011                 }
       
  1012             else
       
  1013                 {
       
  1014                 indicationData = connection->iTurnBinding->HandleDataL(
       
  1015                     aMessage, consumed, peerAddrFromIndication );
       
  1016                 }
       
  1017             }
       
  1018         
       
  1019         if ( consumed )
       
  1020             {
       
  1021             consumingBindingInd = connInd;
       
  1022             aConsumed = ETrue;
       
  1023             }
       
  1024         
       
  1025         connInd--;
       
  1026         }
       
  1027     
       
  1028     delete indicationData;
       
  1029     }
       
  1030 
       
  1031 
       
  1032 // ---------------------------------------------------------------------------
       
  1033 // from base class MNcmOutgoingConnectionObserver
       
  1034 // CNATFWTurnConnectionHandler::OutgoingMessageL
       
  1035 // ---------------------------------------------------------------------------
       
  1036 //
       
  1037 void CNATFWTurnConnectionHandler::OutgoingMessageL(
       
  1038     TUint aStreamId,
       
  1039     TUint aConnectionId,
       
  1040     const TInetAddr& aPeerAddr,
       
  1041     const TDesC8& aMessage,
       
  1042     TBool& aConsumed )
       
  1043     {
       
  1044     __TURNPLUGIN( "CNATFWTurnConnectionHandler::OutgoingMessageL" )
       
  1045     
       
  1046     aConsumed = EFalse;
       
  1047     
       
  1048     TBool controlMsgDetected( EFalse );
       
  1049     TRAPD( err, controlMsgDetected = IsRequestOrIndicationL( aMessage ) )
       
  1050     
       
  1051     if ( !controlMsgDetected || err ) // Prevent loopback in msg handling
       
  1052         {        
       
  1053         TInt streamInd( IndexByStreamId( aStreamId ) );
       
  1054         TConnectionData* connection( NULL );
       
  1055         
       
  1056         if ( KErrNotFound != streamInd )
       
  1057             {
       
  1058             connection = ConnectionById( streamInd, aConnectionId );
       
  1059             }
       
  1060         
       
  1061         if ( connection )
       
  1062             {
       
  1063             aConsumed = ETrue;
       
  1064             
       
  1065             if ( aPeerAddr.IsUnspecified() )
       
  1066                 {
       
  1067                 if ( TConnectionData::EActDestNoneSet == connection->
       
  1068                     iActDestState || TConnectionData::EActDestTransitioning ==
       
  1069                     connection->iActDestState )
       
  1070                     {
       
  1071                     __TURNPLUGIN( "CNATFWTurnConnectionHandler::\
       
  1072                     OutgoingMessageL  Media will be sent in indication" )
       
  1073                     
       
  1074                     connection->iTurnBinding->SendIndicationL( connection->
       
  1075                         iPeerAddr, aMessage, EFalse );
       
  1076                     }
       
  1077                 else
       
  1078                     {
       
  1079                     __TURNPLUGIN( "CNATFWTurnConnectionHandler::\
       
  1080                     OutgoingMessageL  Media will be sent directly" )
       
  1081                     
       
  1082                     if ( KProtocolInetTcp == iStreamArray[streamInd].
       
  1083                         iTransportProtocol )
       
  1084                         {
       
  1085                         CNATFWUNSAFTcpRelayPacket* packet =
       
  1086                             CNATFWUNSAFTcpRelayPacket::NewLC( aMessage,
       
  1087                                 CNATFWUNSAFTcpRelayPacket::EFrameTypeData);
       
  1088                         
       
  1089                         CBufBase* message = packet->EncodeL();
       
  1090                         CleanupStack::PopAndDestroy( packet );
       
  1091                         
       
  1092                         CleanupStack::PushL( message );
       
  1093                         iConnMux->SendL( aStreamId, connection->iConnectionId,
       
  1094                             message->Ptr(0), ETrue );
       
  1095                         CleanupStack::PopAndDestroy( message );
       
  1096                         }
       
  1097                     else
       
  1098                         {
       
  1099                         iConnMux->SendL( aStreamId, connection->iConnectionId,
       
  1100                             aMessage, ETrue );
       
  1101                         }
       
  1102                     }
       
  1103                 }
       
  1104             else
       
  1105                 {
       
  1106                 // Must be protocol message, send in indication(TURNbis-03, 4)
       
  1107                 __TURNPLUGIN( "CNATFWTurnConnectionHandler::\
       
  1108                     OutgoingMessageL  PROTOCOL MSG will be sent" )
       
  1109                 __TURNPLUGIN_ADDRLOG( 
       
  1110                     "CNATFWTurnConnectionHandler::OutgoingMessageL PEERADDR",
       
  1111                     aPeerAddr )
       
  1112                 connection->iTurnBinding->SendIndicationL( aPeerAddr,
       
  1113                     aMessage, EFalse );
       
  1114                 }
       
  1115             }
       
  1116         }
       
  1117     }
       
  1118 
       
  1119 
       
  1120 // ---------------------------------------------------------------------------
       
  1121 // from base class MNcmMessageObserver
       
  1122 // CNATFWTurnConnectionHandler::IncomingMessageNotify
       
  1123 // ---------------------------------------------------------------------------
       
  1124 //
       
  1125 HBufC8* CNATFWTurnConnectionHandler::IncomingMessageNotify(
       
  1126     TUint aStreamId,
       
  1127     const TDesC8& aMessage,
       
  1128     const TInetAddr& aLocalAddr,
       
  1129     const TInetAddr& aFromAddr,
       
  1130     TInetAddr& aPeerAddr )
       
  1131     {
       
  1132     __TURNPLUGIN( "CNATFWTurnConnectionHandler::IncomingMessageNotify" )
       
  1133     
       
  1134     HBufC8* modifiedMessage( NULL );
       
  1135     TRAPD( error, modifiedMessage = HandleIncomingMessageL( 
       
  1136         aStreamId, aMessage, aLocalAddr, aFromAddr, aPeerAddr ) )
       
  1137     if ( KErrNone == error )
       
  1138         {
       
  1139         return modifiedMessage;
       
  1140         }
       
  1141     else
       
  1142         {
       
  1143         __TURNPLUGIN_INT1(
       
  1144             "CNATFWTurnConnectionHandler::IncomingMessageNotify ERR", error )
       
  1145         
       
  1146         return NULL;
       
  1147         }
       
  1148     }
       
  1149 
       
  1150 
       
  1151 // ---------------------------------------------------------------------------
       
  1152 // from base class MNcmMessageObserver
       
  1153 // CNATFWTurnConnectionHandler::OutgoingMessageNotify
       
  1154 // ---------------------------------------------------------------------------
       
  1155 //
       
  1156 HBufC8* CNATFWTurnConnectionHandler::OutgoingMessageNotify(
       
  1157     TUint /*aStreamId*/,
       
  1158     TUint /*aConnectionId*/,
       
  1159     const TInetAddr& /*aDestinationAddress*/,
       
  1160     const TDesC8& /*aMessage*/ )
       
  1161     {
       
  1162     __TURNPLUGIN( "CNATFWTurnConnectionHandler::OutgoingMessageNotify" )
       
  1163     
       
  1164     return NULL;
       
  1165     }
       
  1166 
       
  1167 
       
  1168 // ---------------------------------------------------------------------------
       
  1169 // from base class MNcmConnectionObserver
       
  1170 // CNATFWTurnConnectionHandler::ConnectionNotify
       
  1171 // ---------------------------------------------------------------------------
       
  1172 //
       
  1173 void CNATFWTurnConnectionHandler::ConnectionNotify(
       
  1174     TUint aStreamId,
       
  1175     TUint aConnectionId,
       
  1176     TConnectionNotifyType aType,
       
  1177     TInt aError )
       
  1178     {
       
  1179     __TURNPLUGIN( "CNATFWTurnConnectionHandler::ConnectionNotify start" )
       
  1180     
       
  1181     TInt streamInd( IndexByStreamId( aStreamId ) );
       
  1182     TConnectionData* connection( NULL );
       
  1183     
       
  1184     if ( KErrNotFound != streamInd )
       
  1185         {
       
  1186         connection = ConnectionById( streamInd, aConnectionId );
       
  1187         }
       
  1188     
       
  1189     if ( connection )
       
  1190         {
       
  1191         if ( aError || EConnectionError == aType )
       
  1192             {
       
  1193             if ( !connection->iLocalCandidate )
       
  1194                 {
       
  1195                 // If error occurs when trying to fetch candidate
       
  1196                 TInt errcode( KClientSpecificError + ( aError ) );
       
  1197                 TRAP_IGNORE( iAsyncCallback->MakeCallbackL(
       
  1198                     TTurnPluginCallbackInfo::EFetchingEnd, aStreamId,
       
  1199                         errcode, NULL ) )
       
  1200                 }
       
  1201             else
       
  1202                 {
       
  1203                 TRAP_IGNORE( iAsyncCallback->MakeCallbackL(
       
  1204                     TTurnPluginCallbackInfo::EError, aStreamId,
       
  1205                         aError, NULL ) )
       
  1206                 }
       
  1207             
       
  1208             // Remove failed entry from array
       
  1209             DeleteStream( streamInd, ETrue );
       
  1210             }
       
  1211         else
       
  1212             {
       
  1213             switch ( aType )
       
  1214                 {
       
  1215                 case ESendingActivated:
       
  1216                     {
       
  1217                     connection->iSendingActivated = ETrue;
       
  1218                     
       
  1219                     if ( !connection->iTurnBinding )
       
  1220                         {
       
  1221                         TRAP_IGNORE( CreateTURNBindingL( aStreamId,
       
  1222                             aConnectionId ) )
       
  1223                         }
       
  1224                     }
       
  1225                     break;
       
  1226                 
       
  1227                 case EReceivingActivated:
       
  1228                     {
       
  1229                     connection->iReceivingActivated = ETrue;
       
  1230                     
       
  1231                     if ( connection->iLocalCandidate )
       
  1232                         {
       
  1233                         TRAP_IGNORE( iAsyncCallback->MakeCallbackL(
       
  1234                             TTurnPluginCallbackInfo::EActiveReceiving,
       
  1235                                 aStreamId, KErrNone, NULL ) )
       
  1236                         }
       
  1237                     }
       
  1238                     break;
       
  1239                 
       
  1240                 case ESendingDeactivated:
       
  1241                     {
       
  1242                     connection->iSendingActivated = EFalse;
       
  1243                     }
       
  1244                     break;
       
  1245                 
       
  1246                 case EReceivingDeactivated:
       
  1247                     {
       
  1248                     connection->iReceivingActivated = EFalse;
       
  1249                     
       
  1250                     if ( connection->iLocalCandidate )
       
  1251                         {
       
  1252                         TRAP_IGNORE( iAsyncCallback->MakeCallbackL(
       
  1253                             TTurnPluginCallbackInfo::EDeactiveReceiving,
       
  1254                                 aStreamId, KErrNone, NULL ) )
       
  1255                         }
       
  1256                     }
       
  1257                     break;
       
  1258                 
       
  1259                 case EConnectionRemoved:
       
  1260                     {
       
  1261                     DeleteStream( streamInd, EFalse );
       
  1262                     }
       
  1263                     break;
       
  1264                 }
       
  1265             }
       
  1266         }
       
  1267     
       
  1268     __TURNPLUGIN( "CNATFWTurnConnectionHandler::ConnectionNotify end" )
       
  1269     }
       
  1270 
       
  1271 
       
  1272 // ---------------------------------------------------------------------------
       
  1273 // from base class MNATFWRefreshObserver
       
  1274 // CNATFWTurnConnectionHandler::BindingRefreshL
       
  1275 // ---------------------------------------------------------------------------
       
  1276 //
       
  1277 void CNATFWTurnConnectionHandler::BindingRefreshL()
       
  1278     {
       
  1279     __TURNPLUGIN( "CNATFWTurnConnectionHandler::BindingRefreshL start" )
       
  1280     
       
  1281     TInt streamCount( iStreamArray.Count() );
       
  1282     
       
  1283     for ( TInt streamInd = 0; streamInd < streamCount; streamInd++ )
       
  1284         {
       
  1285         TInt connCount( iStreamArray[streamInd].iConnArray.Count() );
       
  1286         
       
  1287         for ( TInt connInd = 0; connInd < connCount; connInd++ )
       
  1288             {
       
  1289             TConnectionData* connection = ConnectionByIndex( streamInd,
       
  1290                 connInd );
       
  1291             connection->iTurnBinding->AllocateRequestL(
       
  1292                 iStreamArray[streamInd].iRtoValue );
       
  1293             }
       
  1294         }
       
  1295     
       
  1296     __TURNPLUGIN( "CNATFWTurnConnectionHandler::BindingRefreshL end" )
       
  1297     }
       
  1298 
       
  1299 
       
  1300 // ---------------------------------------------------------------------------
       
  1301 // from base class MNATFWTimerObserver
       
  1302 // CNATFWTurnConnectionHandler::TimerTriggeredL
       
  1303 // ---------------------------------------------------------------------------
       
  1304 //
       
  1305 void CNATFWTurnConnectionHandler::TimerTriggeredL( TUint aStreamId,
       
  1306                                                    TUint aConnectionId )
       
  1307     {
       
  1308     __TURNPLUGIN( "CNATFWTurnConnectionHandler::TimerTriggeredL start" )
       
  1309     
       
  1310     TInt streamInd( IndexByStreamId( aStreamId ) );
       
  1311     TConnectionData* connection( NULL );
       
  1312     
       
  1313     if ( KErrNotFound != streamInd )
       
  1314         {
       
  1315         connection = ConnectionById( streamInd, aConnectionId );
       
  1316         }
       
  1317     
       
  1318     if ( connection )
       
  1319         {
       
  1320         if ( TConnectionData::EActDestTransitioning == connection->
       
  1321             iActDestState )
       
  1322             {
       
  1323             // Once the timer fires, if the REMOTE-ADDRESS was not absent
       
  1324             // from the Set Active Destination request which caused the
       
  1325             // client to start the timer, the client moves back to the
       
  1326             // "Set" state, and then updates the value of the active
       
  1327             // destination to the value of REMOTE-ADDRESS.
       
  1328             
       
  1329             if ( !connection->iPeerAddr.IsUnspecified() )
       
  1330                 {
       
  1331                 // Plug-in's client changed Active Destination on
       
  1332                 // server successfully.
       
  1333                 
       
  1334                 connection->iActDestState = TConnectionData::EActDestSet;
       
  1335                 connection->iCurrentActDest.SetAddress( connection->iPeerAddr.
       
  1336                     Address() );
       
  1337                 connection->iCurrentActDest.SetPort( connection->iPeerAddr.
       
  1338                     Port() );
       
  1339                 
       
  1340                 iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
  1341                     EActiveSending, iStreamArray[streamInd].iStreamId,
       
  1342                         KErrNone, NULL );
       
  1343                 }
       
  1344             else
       
  1345             // If REMOTE-ADDRESS was absent, the client sets the Active
       
  1346             // Destination to null and enders the "None Set" state.
       
  1347                 {
       
  1348                 // Plug-in's client resetted Active Destination on
       
  1349                 // server successfully.
       
  1350                 
       
  1351                 connection->iActDestState = TConnectionData::EActDestNoneSet;
       
  1352                 connection->iCurrentActDest = KAFUnspec;
       
  1353                 
       
  1354                 iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
  1355                     EDeactiveSending, iStreamArray[streamInd].iStreamId,
       
  1356                         KErrNone, NULL );
       
  1357                 }
       
  1358             }
       
  1359         else if ( TConnectionData::EActDestNoneSet == connection->
       
  1360             iActDestState )
       
  1361             {
       
  1362             if ( !connection->iActDestAlreadySetOnServer )
       
  1363                 {
       
  1364                 connection->iActDestState = TConnectionData::EActDestSet;
       
  1365                 connection->iCurrentActDest.SetAddress( connection->iPeerAddr.
       
  1366                     Address() );
       
  1367                 connection->iCurrentActDest.SetPort( connection->iPeerAddr.
       
  1368                     Port() );
       
  1369                 }
       
  1370             else
       
  1371                 {
       
  1372                 connection->iActDestAlreadySetOnServer = EFalse;
       
  1373                 
       
  1374                 // Active Destination was reset on server so now
       
  1375                 // try to set Active Destination to remote address.
       
  1376                 connection->iTurnBinding->SetActiveDestinationRequestL(
       
  1377                     connection->iPeerAddr, connection->iTimerValue );
       
  1378                 }
       
  1379             }
       
  1380         else
       
  1381             {
       
  1382             if ( !connection->iActDestReqResent )
       
  1383                 {
       
  1384                 // As server was on "transitioning" state for the first
       
  1385                 // Set Active Destination Request, a new request will
       
  1386                 // be sent only once.
       
  1387                 connection->iActDestReqResent = ETrue;
       
  1388                 
       
  1389                 connection->iTurnBinding->SetActiveDestinationRequestL(
       
  1390                     connection->iPeerAddr, connection->iTimerValue );
       
  1391                 }
       
  1392             else
       
  1393                 {
       
  1394                 iAsyncCallback->MakeCallbackL( TTurnPluginCallbackInfo::
       
  1395                     EActiveSending, aStreamId, KErrNotReady, NULL );
       
  1396                 }
       
  1397             }
       
  1398         }
       
  1399     
       
  1400     __TURNPLUGIN( "CNATFWTurnConnectionHandler::TimerTriggeredL end" )
       
  1401     }
       
  1402 
       
  1403 
       
  1404 // ---------------------------------------------------------------------------
       
  1405 // CNATFWTurnConnectionHandler::DeleteStream
       
  1406 // ---------------------------------------------------------------------------
       
  1407 //
       
  1408 void CNATFWTurnConnectionHandler::DeleteStream( TUint aStreamInd, 
       
  1409     TBool aRemoveMuxConn )
       
  1410     {
       
  1411     __TURNPLUGIN( "CNATFWTurnConnectionHandler::DeleteStream, start" )
       
  1412     ASSERT( aStreamInd < TUint( iStreamArray.Count() ) );
       
  1413     
       
  1414     TRAP_IGNORE(
       
  1415         iConnMux->UnregisterConnectionObserverL(
       
  1416             iStreamArray[aStreamInd].iStreamId, *this ) )
       
  1417     
       
  1418     TRAP_IGNORE(
       
  1419         iConnMux->UnregisterIncomingConnectionObserverL(
       
  1420             iStreamArray[aStreamInd].iStreamId, *this ) )
       
  1421     
       
  1422     TRAP_IGNORE(
       
  1423         iConnMux->UnregisterOutgoingConnectionObserverL(
       
  1424             iStreamArray[aStreamInd].iStreamId, *this ) )
       
  1425     
       
  1426     TRAP_IGNORE(
       
  1427         iConnMux->UnregisterMessageObserverL(
       
  1428             iStreamArray[aStreamInd].iStreamId, *this ) )
       
  1429     
       
  1430     // Remove the stream's connections
       
  1431     TInt connIndex( iStreamArray[aStreamInd].iConnArray.Count() - 1 );
       
  1432     
       
  1433     for ( TInt i( connIndex ); i >= 0; i-- )
       
  1434         {
       
  1435         TConnectionData* connection = ConnectionByIndex( aStreamInd, i );
       
  1436         
       
  1437         if( connection->iTurnBinding )
       
  1438             {
       
  1439             connection->iTurnBinding->CancelRequest();
       
  1440             
       
  1441             delete connection->iTurnBinding;
       
  1442             connection->iTurnBinding = NULL;
       
  1443             delete connection->iLocalCandidate;
       
  1444             connection->iLocalCandidate = NULL;
       
  1445             }
       
  1446         
       
  1447         if ( aRemoveMuxConn )
       
  1448             {
       
  1449             TRAP_IGNORE( iConnMux->RemoveConnectionL(
       
  1450                 iStreamArray[aStreamInd].iStreamId, connection->
       
  1451                     iConnectionId ) )
       
  1452             }
       
  1453         
       
  1454         iStreamArray[aStreamInd].iConnArray.Remove( i );
       
  1455         }
       
  1456     
       
  1457     iStreamArray[aStreamInd].iConnArray.Close();
       
  1458     iStreamArray.Remove( aStreamInd );
       
  1459     
       
  1460     __TURNPLUGIN( "CNATFWTurnConnectionHandler::DeleteStream, end" )
       
  1461     }
       
  1462 
       
  1463 
       
  1464 // ---------------------------------------------------------------------------
       
  1465 // CNATFWTurnConnectionHandler::FindConnection
       
  1466 // Function expects that system does not have multiple TURN-connections bound
       
  1467 // to the same local address and stream.
       
  1468 // ---------------------------------------------------------------------------
       
  1469 //
       
  1470 TConnectionData* CNATFWTurnConnectionHandler::FindConnection(
       
  1471     TUint aStreamId,
       
  1472     const TInetAddr& aLocalAddr )
       
  1473     {
       
  1474     // find stream index
       
  1475     TInt foundStreamInd( KErrNotFound );
       
  1476     TInt streamInd( iStreamArray.Count() - 1 );
       
  1477     while ( KErrNotFound == foundStreamInd && 0 <= streamInd )
       
  1478         {
       
  1479         if ( iStreamArray[streamInd].iStreamId == aStreamId )
       
  1480             {
       
  1481             foundStreamInd = streamInd;
       
  1482             }
       
  1483         
       
  1484         streamInd--;
       
  1485         }
       
  1486     
       
  1487     TInt foundConnectionInd( KErrNotFound );
       
  1488     if ( KErrNotFound != foundStreamInd )
       
  1489         {
       
  1490         // find connection inside stream
       
  1491         const RArray<TConnectionData>& connArray( 
       
  1492             iStreamArray[foundStreamInd].iConnArray );
       
  1493         TInt connectionInd( connArray.Count() - 1 );
       
  1494         
       
  1495         while ( KErrNotFound == foundConnectionInd && 0 <= connectionInd )
       
  1496             {
       
  1497             const TInetAddr& localAddr( connArray[connectionInd].iLocalAddr );
       
  1498             
       
  1499             if ( MatchAddresses( localAddr, aLocalAddr ) )
       
  1500                 {
       
  1501                 foundConnectionInd = connectionInd;
       
  1502                 }
       
  1503             
       
  1504             connectionInd--;
       
  1505             }
       
  1506         }
       
  1507     
       
  1508     if ( ( KErrNotFound != foundStreamInd ) && 
       
  1509          ( KErrNotFound != foundConnectionInd ) )
       
  1510         {
       
  1511         return &(iStreamArray[foundStreamInd].iConnArray[foundConnectionInd]);
       
  1512         }
       
  1513     else
       
  1514         {
       
  1515         return NULL;
       
  1516         }
       
  1517     }
       
  1518 
       
  1519 
       
  1520 // ---------------------------------------------------------------------------
       
  1521 // CNATFWTurnConnectionHandler::HandleIncomingMessageL
       
  1522 // ---------------------------------------------------------------------------
       
  1523 //
       
  1524 HBufC8* CNATFWTurnConnectionHandler::HandleIncomingMessageL(
       
  1525     TUint aStreamId,
       
  1526     const TDesC8& aMessage,
       
  1527     const TInetAddr& aLocalAddr,
       
  1528     const TInetAddr& aFromAddr,
       
  1529     TInetAddr& aPeerAddr )
       
  1530     {
       
  1531     CNATFWUNSAFMessageFactory* decoder = CNATFWUNSAFMessageFactory::NewLC();
       
  1532     CNATFWUNSAFMessage* msg( NULL );
       
  1533     TRAPD( error, msg = decoder->DecodeL( aMessage ) )
       
  1534     CleanupStack::PopAndDestroy( decoder );
       
  1535     CleanupStack::PushL( msg );
       
  1536     
       
  1537     if ( error || NULL == msg )
       
  1538         {
       
  1539         // Not STUN message, must be media
       
  1540         TConnectionData* activeConnection( NULL );
       
  1541         TInt streamInd( iStreamArray.Count() - 1 );
       
  1542         
       
  1543         while ( !activeConnection && 0 <= streamInd )
       
  1544             {
       
  1545             TInt connInd = iStreamArray[streamInd].iConnArray.Count() - 1;
       
  1546             
       
  1547             while ( !activeConnection && 0 <= connInd )
       
  1548                 {
       
  1549                 activeConnection = ConnectionByIndex( streamInd, connInd );
       
  1550                 
       
  1551                 if ( TConnectionData::EActDestSet != activeConnection->
       
  1552                     iActDestState )
       
  1553                     {
       
  1554                     activeConnection = NULL;
       
  1555                     }
       
  1556                 
       
  1557                 connInd--;
       
  1558                 }
       
  1559             
       
  1560             streamInd--;
       
  1561             }
       
  1562         
       
  1563         if ( activeConnection )
       
  1564             {
       
  1565             aPeerAddr = activeConnection->iCurrentActDest;
       
  1566             }
       
  1567         else
       
  1568             {
       
  1569             aPeerAddr = aFromAddr;
       
  1570             }
       
  1571         
       
  1572         CleanupStack::PopAndDestroy( msg );
       
  1573         return NULL;
       
  1574         }
       
  1575     
       
  1576     if ( msg->Type() == CNATFWUNSAFMessage::EDataIndication )
       
  1577         {
       
  1578         // Must be data from peer, either protocol message or media
       
  1579         // from nonactivated peer address
       
  1580         CNATFWUNSAFRemoteAddressAttribute* remoteAddress =
       
  1581             static_cast<CNATFWUNSAFRemoteAddressAttribute*>
       
  1582             ( msg->Attribute( CNATFWUNSAFAttribute::ERemoteAddress ) );
       
  1583         
       
  1584         if ( remoteAddress )
       
  1585             {
       
  1586             aPeerAddr = remoteAddress->Address();
       
  1587             __TURNPLUGIN_ADDRLOG( 
       
  1588                "CNATFWTurnConnectionHandler::HandleIncomingMessageL DATAIND",
       
  1589                aPeerAddr )
       
  1590             }
       
  1591         else
       
  1592             {
       
  1593             __TURNPLUGIN( 
       
  1594                 "CNATFWTurnConnectionHandler::HandleIncomingMessageL, \
       
  1595                 NO REMOTE ADDR FIELD" )
       
  1596             }
       
  1597         
       
  1598         const TDesC8& data = static_cast<CNATFWUNSAFDataAttribute*>(
       
  1599             msg->Attribute( CNATFWUNSAFAttribute::EData ) )->Value();
       
  1600         
       
  1601         HBufC8* modifiedMsg = data.AllocL();
       
  1602         CleanupStack::PopAndDestroy( msg );
       
  1603         return modifiedMsg;
       
  1604         }
       
  1605     else
       
  1606         {
       
  1607         // This is either response from physical TURN-server or STUN-data from
       
  1608         // peer address which is set as active destination.
       
  1609         TConnectionData* activeConnection 
       
  1610             = FindConnection( aStreamId, aLocalAddr );
       
  1611         
       
  1612         if ( activeConnection && 
       
  1613                 !activeConnection->iCurrentActDest.IsUnspecified() )
       
  1614             {
       
  1615             aPeerAddr = activeConnection->iCurrentActDest;
       
  1616             }
       
  1617         else
       
  1618             {
       
  1619             aPeerAddr = aFromAddr;
       
  1620             }
       
  1621         
       
  1622         __TURNPLUGIN_ADDRLOG( 
       
  1623             "CNATFWTurnConnectionHandler::HandleIncomingMessageL NOT DATAIND",
       
  1624             aPeerAddr )
       
  1625         
       
  1626         CleanupStack::PopAndDestroy( msg );
       
  1627         return NULL;
       
  1628         }
       
  1629     }
       
  1630 
       
  1631 
       
  1632 // ---------------------------------------------------------------------------
       
  1633 // CNATFWTurnConnectionHandler::IndexByStreamId
       
  1634 // ---------------------------------------------------------------------------
       
  1635 //
       
  1636 TInt CNATFWTurnConnectionHandler::IndexByStreamId( TUint aStreamId )
       
  1637     {
       
  1638     __TURNPLUGIN( "CNATFWTurnConnectionHandler::IndexByStreamId" )
       
  1639     
       
  1640     TInt index( iStreamArray.Count() - 1 );
       
  1641     
       
  1642     while ( 0 <= index )
       
  1643         {
       
  1644         if ( aStreamId == iStreamArray[index].iStreamId )
       
  1645             {
       
  1646             return index;
       
  1647             }
       
  1648         
       
  1649         index--;
       
  1650         }
       
  1651 
       
  1652     return KErrNotFound;
       
  1653     }
       
  1654 
       
  1655 
       
  1656 // ---------------------------------------------------------------------------
       
  1657 // CNATFWTurnConnectionHandler::ConnectionById
       
  1658 // ---------------------------------------------------------------------------
       
  1659 //
       
  1660 TConnectionData* CNATFWTurnConnectionHandler::ConnectionById(
       
  1661     TUint aStreamInd,
       
  1662     TUint aConnectionId )
       
  1663     {
       
  1664     __TURNPLUGIN( "CNATFWTurnConnectionHandler::ConnectionById" )
       
  1665     
       
  1666     TInt index( iStreamArray[aStreamInd].iConnArray.Count() - 1 );
       
  1667     
       
  1668     while ( 0 <= index )
       
  1669         {
       
  1670         if ( aConnectionId == iStreamArray[aStreamInd].iConnArray[index].
       
  1671             iConnectionId )
       
  1672             {
       
  1673             return &iStreamArray[aStreamInd].iConnArray[index];
       
  1674             }
       
  1675         
       
  1676         index--;
       
  1677         }
       
  1678     
       
  1679     return NULL;
       
  1680     }
       
  1681 
       
  1682 
       
  1683 // ---------------------------------------------------------------------------
       
  1684 // CNATFWTurnConnectionHandler::ConnectionByIndex
       
  1685 // ---------------------------------------------------------------------------
       
  1686 //
       
  1687 TConnectionData* CNATFWTurnConnectionHandler::ConnectionByIndex(
       
  1688     TUint aStreamInd,
       
  1689     TUint aConnectionInd )
       
  1690     {
       
  1691     __TURNPLUGIN( "CNATFWTurnConnectionHandler::ConnectionByIndex" )
       
  1692     
       
  1693     return &iStreamArray[aStreamInd].iConnArray[aConnectionInd];
       
  1694     }
       
  1695 
       
  1696 
       
  1697 // ---------------------------------------------------------------------------
       
  1698 // CNATFWTurnConnectionHandler::GenerateServerListL
       
  1699 // ---------------------------------------------------------------------------
       
  1700 //
       
  1701 void CNATFWTurnConnectionHandler::GenerateServerListL()
       
  1702     {
       
  1703     __TURNPLUGIN( "CNATFWTurnConnectionHandler::GenerateServerListL start" )
       
  1704     
       
  1705     RPointerArray<MNATFWServerSettings> serverArray;
       
  1706     iTurnSettings->GetTurnServerArrayL( serverArray );
       
  1707     CleanupClosePushL( serverArray );
       
  1708     TInt count( serverArray.Count() );
       
  1709     
       
  1710     HBufC8* serverAddress =
       
  1711         iTurnSettings->LatestConnectedServerAddr().AllocLC();
       
  1712     TUint latestPort = iTurnSettings->LatestConnectedServerPort();
       
  1713     
       
  1714     // Add Latest connected server
       
  1715     if ( serverAddress->Compare( KNullDesC8 ) )
       
  1716         {
       
  1717         CTurnServerSettings* settings = CTurnServerSettings::NewLC();
       
  1718         settings->SetAddressL( *serverAddress );
       
  1719         settings->SetPort( latestPort );
       
  1720         
       
  1721         for ( TInt index( 0 ); index < count; index++ )
       
  1722             {
       
  1723             if ( *serverAddress == serverArray[index]->Address() &&
       
  1724                 serverArray[index]->Username().Length() &&
       
  1725                 serverArray[index]->Password().Length() )
       
  1726                 {
       
  1727                 settings->SetUsernameL( serverArray[index]->Username() );
       
  1728                 settings->SetPasswordL( serverArray[index]->Password() );
       
  1729                 break;
       
  1730                 }
       
  1731             }
       
  1732             
       
  1733         if ( settings->Address().Compare( KNullDesC8 ) )
       
  1734             {
       
  1735             __TURNPLUGIN( "CNATFWStunConnectionHandler::GenerateServerListL\
       
  1736             - provisioned server added" )
       
  1737             }
       
  1738             
       
  1739         iServerList.AppendL( settings );
       
  1740         CleanupStack::Pop( settings );
       
  1741         }
       
  1742     
       
  1743     CleanupStack::PopAndDestroy( serverAddress );
       
  1744     
       
  1745     // Add provisioned servers
       
  1746     for ( TInt index( 0 ); index < count; index++ )
       
  1747         {
       
  1748         CTurnServerSettings* settings = CTurnServerSettings::NewLC();
       
  1749         
       
  1750         settings->SetAddressL( serverArray[index]->Address() );
       
  1751         settings->SetPort( serverArray[index]->Port() );
       
  1752         
       
  1753         if ( serverArray[index]->Username().Length() &&
       
  1754             serverArray[index]->Password().Length() )
       
  1755             {
       
  1756             settings->SetUsernameL( serverArray[index]->Username() );
       
  1757             settings->SetPasswordL( serverArray[index]->Password() );
       
  1758             }
       
  1759         
       
  1760         iServerList.AppendL( settings );
       
  1761         CleanupStack::Pop( settings );
       
  1762         }
       
  1763     
       
  1764     // Domain
       
  1765     CTurnServerSettings* settings = CTurnServerSettings::NewLC();
       
  1766     settings->SetAddressL( *iDomain );
       
  1767     settings->SetPort( ( latestPort ) ? latestPort : KDefaultStunSrvPort );
       
  1768     
       
  1769     for ( TInt index( 0 ); index < count; index++ )
       
  1770         {
       
  1771         if ( *iDomain == serverArray[index]->Address() &&
       
  1772             serverArray[index]->Username().Length() &&
       
  1773             serverArray[index]->Password().Length() )
       
  1774             {
       
  1775             settings->SetUsernameL( serverArray[index]->Username() );
       
  1776             settings->SetPasswordL( serverArray[index]->Password() );
       
  1777             break;
       
  1778             }
       
  1779         }
       
  1780     
       
  1781     iServerList.AppendL( settings );
       
  1782     CleanupStack::Pop( settings );
       
  1783     CleanupStack::PopAndDestroy( &serverArray );
       
  1784     
       
  1785     __TURNPLUGIN( "CNATFWTurnConnectionHandler::GenerateServerListL end" )
       
  1786     }
       
  1787 
       
  1788 
       
  1789 // ---------------------------------------------------------------------------
       
  1790 // CNATFWStunConnectionHandler::TryNextServerL
       
  1791 // ---------------------------------------------------------------------------
       
  1792 //
       
  1793 void CNATFWTurnConnectionHandler::TryNextServerL()
       
  1794     {
       
  1795     __TURNPLUGIN( "CNATFWTurnConnectionHandler::TryNextServerL start" )
       
  1796     
       
  1797     delete iStunClient;
       
  1798     iStunClient = NULL;
       
  1799     
       
  1800     if ( iServerIndex < iServerList.Count() )
       
  1801         {
       
  1802         TInt index( iServerIndex );
       
  1803         iServerIndex++;
       
  1804         
       
  1805         TInt refresh( iNatSettings->RefreshIntervalUdp() );
       
  1806         iTurnRefreshInterval = ( refresh ) ? ( refresh * KMicrosecFactor ) :
       
  1807             KDefaultRefreshInterval;
       
  1808         
       
  1809         TInt retransmitInterval( iTurnSettings->RetransmissionTimeout() );
       
  1810         
       
  1811         TUint port = iServerList[index]->Port() ? iServerList[index]->Port() :
       
  1812             KDefaultStunSrvPort;
       
  1813         
       
  1814         iStunClient = CSTUNClient::NewL( retransmitInterval,
       
  1815                                          iServerList[index]->Address(),
       
  1816                                          port,
       
  1817                                          KStunRelay,
       
  1818                                          iSocketServ,
       
  1819                                          iConnection,
       
  1820                                          *iTimerServ,
       
  1821                                          *this,
       
  1822                                          ETrue,
       
  1823                                          EFalse,
       
  1824                                          EFalse,
       
  1825                                          iConnMux );
       
  1826         
       
  1827         if ( iServerList[index]->Username() && iServerList[index]->
       
  1828             Password() )
       
  1829             {
       
  1830             TRAP_IGNORE( iStunClient->SetCredentialsL( *iServerList[index]->
       
  1831                 Username(), *iServerList[index]->Password() ) )
       
  1832             }
       
  1833         }
       
  1834     else
       
  1835         {
       
  1836         User::Leave( KErrNotFound );
       
  1837         }
       
  1838     
       
  1839     __TURNPLUGIN( "CNATFWTurnConnectionHandler::TryNextServerL end" )
       
  1840     }
       
  1841 
       
  1842 
       
  1843 // ---------------------------------------------------------------------------
       
  1844 // CNATFWTurnConnectionHandler::MatchAddresses
       
  1845 // ---------------------------------------------------------------------------
       
  1846 //
       
  1847 TBool CNATFWTurnConnectionHandler::MatchAddresses( const TInetAddr& aAddr1,
       
  1848     const TInetAddr& aAddr2 )
       
  1849     {
       
  1850     // CmpAddr does not interpret IPv4 and IPv4 mapped/compatible addresses
       
  1851     // as same even if they represent same address. Thus extra testing is
       
  1852     // needed to handle that case.
       
  1853     TBool isMatch = ( aAddr1.CmpAddr( aAddr2 ) || ( aAddr1.Address() ==
       
  1854         aAddr2.Address() && aAddr1.Port() == aAddr2.Port() ) );
       
  1855     
       
  1856     return isMatch;
       
  1857     }
       
  1858 
       
  1859 // End of file