natfw/natfwicecandidatehandler/src/cicehostresolver.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/natfw/natfwicecandidatehandler/src/cicehostresolver.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,424 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:    Resolves host candidates for the streams.
+*
+*/
+
+
+
+
+#include "mncmconnectionmultiplexer.h"
+#include "natfwcandidate.h"
+#include "mnatfwpluginobserver.h"
+#include "cicehostresolver.h"
+#include "ciceconnection.h"
+#include "cicecallbackexecuter.h"
+#include "icecandidatehandlerdefs.h"
+#include "icecandidatehandlerlogs.h"
+
+
+// ======== MEMBER FUNCTIONS ========
+
+CIceHostResolver::CIceHostResolver()
+    {
+
+    }
+
+
+void CIceHostResolver::ConstructL( TAny* aInitParams )
+    {
+    __ICEDP( "CIceHostResolver::ConstructL" )
+    __ASSERT_ALWAYS( aInitParams, User::Leave( KErrArgument ) );
+    
+    iPluginId = KNatPluginIdNokiaHost().AllocL();
+    
+    CNATFWPluginApi::TNATFWPluginInitParams* initParams = 
+        static_cast<CNATFWPluginApi::TNATFWPluginInitParams*>
+        ( aInitParams );
+    
+    iPluginObserver = &(initParams->iObserver);
+    iMultiplexer = &initParams->iMultiplexer;
+    iCallBackExecuter 
+        = CIceCallBackExecuter::NewL( CActive::EPriorityStandard );
+    }
+
+
+CIceHostResolver* CIceHostResolver::NewL( TAny* aInitParams )
+    {
+    CIceHostResolver* self = new( ELeave ) CIceHostResolver();
+    CleanupStack::PushL( self );
+    self->ConstructL( aInitParams );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+CIceHostResolver::~CIceHostResolver()
+    {
+    __ICEDP( "CIceHostResolver::~CIceHostResolver" )
+    
+    delete iPluginId;
+    iPluginObserver = NULL;
+    iMultiplexer = NULL;
+    iHostCandidates.ResetAndDestroy();
+    delete iCallBackExecuter;
+    
+    iConnections.ResetAndDestroy();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIceHostResolver::HandleCallBack
+// ---------------------------------------------------------------------------
+//
+void CIceHostResolver::HandleCallBack( CBase& aObject, TInt aCallBackType )
+    {
+    __ICEDP( "CIceHostResolver::HandleCallBack" )
+    
+    CIceHostResolver& plugin( static_cast<CIceHostResolver&>( aObject ) );
+    plugin.DoHandleCallBack( aCallBackType );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIceHostResolver::LocalAddress
+// ---------------------------------------------------------------------------
+//
+TInetAddr CIceHostResolver::LocalAddress( 
+        TUint aStreamId, TUint aAddrFamily ) const
+    {
+    __ICEDP( "CIceHostResolver::LocalAddress" )
+
+    TInt count( iConnections.Count() );
+    ASSERT( count );
+
+    for ( TInt i( 0 ); i < count; i++ )
+        {
+        if ( iConnections[i]->StreamId() == aStreamId &&
+             iConnections[i]->LocalAddress().Family() == aAddrFamily )
+            {
+            return iConnections[i]->LocalAddress();
+            }
+        }
+    
+    return TInetAddr();
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class CNATFWPluginApi.
+// ---------------------------------------------------------------------------
+//    
+void CIceHostResolver::ConnectServerL( const RSocketServ& /*aSocketServ*/,
+        const TName& /*aConnectionName*/ )
+    {
+    __ICEDP( "CIceHostResolver::ConnectServerL" )
+    
+    TIceCallBack callback(
+        HandleCallBack, *this, ECallBackServerConnected, 0 );
+    iCallBackExecuter->AddCallBackL( callback );
+    }
+    
+
+// ---------------------------------------------------------------------------
+// From class CNATFWPluginApi.
+// ---------------------------------------------------------------------------
+//
+void CIceHostResolver::FetchCandidateL( TUint aStreamId, TUint /*aRtoValue*/,
+        TUint aAddrFamily )
+    {
+    __ICEDP( "CIceHostResolver::FetchCandidateL" )
+    
+    CIceConnection* connection = CIceConnection::NewLC( 
+        aStreamId, aAddrFamily, *iMultiplexer, *this );
+    iConnections.AppendL( connection );
+    CleanupStack::Pop( connection );
+    
+    // Host connections are used to receive checks from peer when local agent
+    // has not yet started ICE processing.
+    connection->SetReceivingStateL( EStreamingStateActive, 
+        CIceConnection::ENotifyStateDisabled );
+    
+    // Unspecified destination allows STUN server response sending to
+    // arbitrary address.
+    TInetAddr unspecDestination;
+    connection->SetSendingStateL( EStreamingStateActive, 
+        CIceConnection::ENotifyStateDisabled, unspecDestination );
+    
+    // setup host candidate
+    const TInetAddr& addr( connection->LocalAddress() );
+    CNATFWCandidate* hostCandidate = CNATFWCandidate::NewLC();
+    hostCandidate->SetStreamId( aStreamId );
+    hostCandidate->SetType( CNATFWCandidate::EHost );
+    hostCandidate->SetTransportAddrL( addr );
+    hostCandidate->SetBase( addr );
+    TUint protocol = connection->TransportProtocol();
+    hostCandidate->SetTransportProtocol( protocol );
+    
+    iHostCandidates.AppendL( hostCandidate );
+    CleanupStack::Pop( hostCandidate );
+    connection->BindWithCandidateL( *hostCandidate );
+    
+    TIceCallBack callback( HandleCallBack, *this, ECallBackCandidateFound, 0 );
+    iCallBackExecuter->AddCallBackL( callback );
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class CNATFWPluginApi.
+// ---------------------------------------------------------------------------
+//
+void CIceHostResolver::SetReceivingStateL(
+        const CNATFWCandidate& aLocalCandidate, TNATFWStreamingState aState )
+    {
+    __ICEDP( "CIceHostResolver::SetReceivingStateL" )
+    __ASSERT_ALWAYS( IsOwnedCandidate( aLocalCandidate ), 
+        User::Leave( KErrNotFound ) );
+    
+    // find connection bound to the candidate
+    CIceConnection* connection = FindConnection( aLocalCandidate );
+    if ( NULL == connection &&
+         CNATFWCandidate::EPeerReflexive == aLocalCandidate.Type() )
+        {
+        // Bind new peer-reflexive candidate with the corresponding host
+        // connection. Peer-reflexive candidate has same base than host
+        // candidate.
+        connection = FindConnection( aLocalCandidate.Base() );
+        if ( connection )
+            {
+            connection->BindWithCandidateL( aLocalCandidate );
+            }
+        }
+    
+    __ASSERT_ALWAYS( NULL != connection, User::Leave( KErrNotFound ) );
+    connection->SetReceivingStateL( aState, 
+        CIceConnection::ENotifyStateEnabled );
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class CNATFWPluginApi.
+// ---------------------------------------------------------------------------
+//
+void CIceHostResolver::SetSendingStateL(
+        const CNATFWCandidate& aLocalCandidate,
+        TNATFWStreamingState aState, const TInetAddr& aDestAddr )
+    {
+    __ICEDP( "CIceHostResolver::SetSendingStateL" )
+    __ASSERT_ALWAYS( IsOwnedCandidate( aLocalCandidate ), 
+        User::Leave( KErrNotFound ) );
+
+    // find connection bound to the candidate
+    CIceConnection* connection = FindConnection( aLocalCandidate );
+    if ( NULL == connection &&
+         CNATFWCandidate::EPeerReflexive == aLocalCandidate.Type() )
+        {
+        // Bind new peer-reflexive candidate with the corresponding host
+        // connection. Peer-reflexive candidate has same base than host
+        // candidate.
+        connection = FindConnection( aLocalCandidate.Base() );
+        if ( connection )
+            {
+            connection->BindWithCandidateL( aLocalCandidate );
+            }
+        }
+    
+    __ASSERT_ALWAYS( NULL != connection, User::Leave( KErrNotFound ) );
+    connection->SetSendingStateL( aState, 
+        CIceConnection::ENotifyStateEnabled, aDestAddr );
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class CNATFWPluginApi.
+// ---------------------------------------------------------------------------
+//
+void CIceHostResolver::GetConnectionIdL(
+        const CNATFWCandidate& aLocalCandidate,
+        TUint& aConnectionId )
+    {
+    __ICEDP( "CIceHostResolver::GetConnectionIdL" )
+    __ASSERT_ALWAYS( IsOwnedCandidate( aLocalCandidate ), 
+        User::Leave( KErrNotFound ) );
+    
+    // find connection bound to the candidate
+    CIceConnection* connection = FindConnection( aLocalCandidate );
+    if ( NULL == connection &&
+         CNATFWCandidate::EPeerReflexive == aLocalCandidate.Type() )
+        {
+        // Bind new peer-reflexive candidate with the corresponding host
+        // connection. Peer-reflexive candidate has same base than host
+        // candidate.
+        connection = FindConnection( aLocalCandidate.Base() );
+        if ( connection )
+            {
+            connection->BindWithCandidateL( aLocalCandidate );
+            }
+        }
+    
+    __ASSERT_ALWAYS( NULL != connection, User::Leave( KErrNotFound ) );
+    aConnectionId = connection->ConnectionId();
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class CNATFWPluginApi.
+// ---------------------------------------------------------------------------
+//
+const TDesC8& CIceHostResolver::PluginIdentifier() const
+    {
+    return *iPluginId;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIceHostResolver::ConnectionNotify
+// Passes media connection related events to the client.
+// ---------------------------------------------------------------------------
+//
+void CIceHostResolver::ConnectionNotify( CIceConnection& aConnection,
+        MIceConnectionObserver::TNotifyType aType, TInt aError )
+    {
+    __ICEDP( "CIceHostResolver::ConnectionNotify" )
+    
+    TInt connectionIndex( iConnections.Find( &aConnection ) );
+    ASSERT( KErrNotFound != connectionIndex );
+    if ( KErrNotFound != connectionIndex )
+        {
+        switch ( aType )
+            {
+            case MIceConnectionObserver::ENotifyConnectionRemoved:
+                delete iConnections[connectionIndex];
+                iConnections.Remove( connectionIndex );
+                break;
+           
+            case MIceConnectionObserver::ENotifyConnectionError:
+                iPluginObserver->Error( *this, aConnection.StreamId(),
+                    aError );
+                break;
+            
+            case MIceConnectionObserver::ENotifyRecvActivated:
+                iPluginObserver->Notify( *this, aConnection.StreamId(), 
+                    MNATFWPluginObserver::EReceivingActivated, aError );
+                break;
+            
+            case MIceConnectionObserver::ENotifyRecvDeactivated:
+                iPluginObserver->Notify( *this, aConnection.StreamId(), 
+                    MNATFWPluginObserver::EReceivingDeactivated, aError );
+                break;
+            
+            case MIceConnectionObserver::ENotifySendActivated:
+                iPluginObserver->Notify( *this, aConnection.StreamId(), 
+                    MNATFWPluginObserver::ESendingActivated, aError );
+                break;
+            
+            case MIceConnectionObserver::ENotifySendDeactivated:
+                iPluginObserver->Notify( *this, aConnection.StreamId(), 
+                    MNATFWPluginObserver::ESendingDeactivated, aError );
+                break;
+            
+            default:
+                ASSERT( EFalse );
+            }       
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIceHostResolver::DoHandleCallBack
+// ---------------------------------------------------------------------------
+//
+void CIceHostResolver::DoHandleCallBack( TInt aCallBackType )
+    {
+    __ICEDP( "CIceHostResolver::DoHandleCallBack" )
+    
+    if ( ECallBackServerConnected == aCallBackType )
+        {
+        iPluginObserver->Notify( *this, 0,
+            MNATFWPluginObserver::EServerConnected, KErrNone );
+        }
+    else if ( ECallBackCandidateFound  == aCallBackType )
+        {
+        ASSERT( iHostCandidates.Count() );
+        TUint streamId( iHostCandidates[0]->StreamId() );
+        iPluginObserver->NewLocalCandidateFound( *this, iHostCandidates[0] );
+        iHostCandidates.Remove( 0 );
+        iPluginObserver->Notify( *this, streamId,
+            MNATFWPluginObserver::EFetchingCompleted, KErrNone );
+        }
+    else
+        {
+        __ICEDP( "CIceHostResolver::DoHandleCallBack, ELSE" )
+        ASSERT( EFalse );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIceHostResolver::FindConnection
+// ---------------------------------------------------------------------------
+//
+CIceConnection* CIceHostResolver::FindConnection( 
+        const CNATFWCandidate& aLocalCandidate )
+    {
+    CIceConnection* foundConnection( NULL );
+    TInt index( iConnections.Count() - 1 );
+    while ( NULL == foundConnection && 0 <= index )
+        {
+        if ( iConnections[index]->IsBoundToCandidate( aLocalCandidate ) )
+            {
+            foundConnection = iConnections[index];
+            }
+        
+        index--;
+        }
+    
+    return foundConnection;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIceHostResolver::FindConnection
+// ---------------------------------------------------------------------------
+//
+CIceConnection* CIceHostResolver::FindConnection( 
+        const TInetAddr& aLocalAddr )
+    {
+    CIceConnection* foundConnection( NULL );
+    TInt index( iConnections.Count() - 1 );
+    while ( NULL == foundConnection && 0 <= index )
+        {
+        if ( TIceUtils::MatchAddresses( 
+                iConnections[index]->LocalAddress(), aLocalAddr ) )
+            {
+            foundConnection = iConnections[index];
+            }
+        
+        index--;
+        }
+    
+    return foundConnection;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIceHostResolver::IsOwnedCandidate
+// ---------------------------------------------------------------------------
+//
+TBool CIceHostResolver::IsOwnedCandidate( 
+        const CNATFWCandidate& aLocalCandidate ) const
+    {
+    return ( CNATFWCandidate::EHost == aLocalCandidate.Type() || 
+             CNATFWCandidate::EPeerReflexive == aLocalCandidate.Type() );
+    }