natplugins/natpnatfwsdpprovider/src/nspmediastreamcomponent.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/natplugins/natpnatfwsdpprovider/src/nspmediastreamcomponent.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,600 @@
+/*
+* 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:  Media stream component class implementation
+*
+*/
+
+#include "natfwcandidate.h"
+#include "natfwcandidatepair.h"
+#include "mnatfwsocketmediaconnwrapper.h"
+#include "nspsessionobserver.h"
+#include "nspmediastreamcomponent.h"
+#include "nspnatfwasyncstate.h"
+#include "nspcontrollerif.h"
+#include "nspdefs.h"
+
+const TUint KNSPFetchCandTimerInMicros = 7000000; // 7 seconds
+const TUint KNSPRtcpComponentId = 2;
+
+#define TOINETADDR_L( aDesc, aPort ) ConvertTDesC8ToTInetAddrL( aDesc, aPort )
+#define NATFWRECEIVING_L( aCand, aState ) \
+	iController.SetReceivingStateL( aCand, aState )
+#define NATFWSENDING_L( aCand, aState ) \
+	iController.SetSendingStateL( aCand, aState, iRemoteAddress, iRemotePort )
+
+
+// ======== MEMBER FUNCTIONS ========
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::CNSPMediaStreamComponent
+// ---------------------------------------------------------------------------
+//
+CNSPMediaStreamComponent::CNSPMediaStreamComponent( MNSPControllerIF& aController,
+        TUint aSessionId, TUint aCollectionId, TUint aComponentId )
+    : iController( aController ),
+      iSessionId( aSessionId ),
+      iCollectionId( aCollectionId ),
+      iComponentId( aComponentId )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CNSPMediaStreamComponent::ConstructL( const TDesC8& aAddress, TUint aPort,
+        TUint aProtocol, TUint aMediaTos )
+    {
+    TInetAddr addr = TOINETADDR_L( aAddress, aPort );
+    iAddrFamily = addr.Family();
+    
+    iStreamId = iController.CreateStreamL( 
+        iSessionId, aProtocol, static_cast<TInt>( aMediaTos ) );
+    iWrapper = &iController.CreateWrapperL( iSessionId, iStreamId );
+    
+    iWrapper->SetIncomingAddrL( addr );
+    iWrapper->SetReceivingStateL( EStreamingStateActive );
+    iWrapper->SetSendingStateL( EStreamingStateActive );
+    
+    iState = CNSPNATFWAsyncState::NewL();
+    iRemoteAddress.Assign( KNullDesC8().AllocL() );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::NewL
+// ---------------------------------------------------------------------------
+//
+CNSPMediaStreamComponent* CNSPMediaStreamComponent::NewL(
+        MNSPControllerIF& aController, TUint aSessionId,
+        TUint aCollectionId, TUint aComponentId, const TDesC8& aAddress,
+        TUint aPort, TUint aProtocol, TUint aMediaTos )
+    {
+    CNSPMediaStreamComponent* self = CNSPMediaStreamComponent::NewLC(
+            aController, aSessionId, aCollectionId, aComponentId,
+            aAddress, aPort, aProtocol, aMediaTos );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::NewLC
+// ---------------------------------------------------------------------------
+//
+CNSPMediaStreamComponent* CNSPMediaStreamComponent::NewLC(
+        MNSPControllerIF& aController, TUint aSessionId, TUint aCollectionId,
+        TUint aComponentId, const TDesC8& aAddress, TUint aPort,
+        TUint aProtocol, TUint aMediaTos )
+    {
+    CNSPMediaStreamComponent* self = new ( ELeave ) CNSPMediaStreamComponent(
+            aController, aSessionId, aCollectionId, aComponentId );
+    CleanupStack::PushL( self );
+    self->ConstructL( aAddress, aPort, aProtocol, aMediaTos );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::~CNSPMediaStreamComponent
+// ---------------------------------------------------------------------------
+//
+CNSPMediaStreamComponent::~CNSPMediaStreamComponent()
+    {
+    iRemoteAddress.Close();
+    iWrapper = NULL;
+    delete iState;
+    delete iCandidatePair;
+    iLocalCandidates.ResetAndDestroy();
+    iLocalCandidates.Close();
+    iController.Cancel( iTimerTransactionId );
+    TRAP_IGNORE( iController.CloseStreamL( iSessionId, iStreamId ) )
+    }
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::ControlMediaL
+// ---------------------------------------------------------------------------
+//
+TNatReturnStatus CNSPMediaStreamComponent::ControlMediaL(
+		MNATFWConnectivityObserver::TNATFWConnectivityEvent aEvent,
+		TInt aError, TAny* aData )
+	{
+    NSPLOG_STR( "CNSPMediaStreamComponent::ControlMediaL(), Entry" )
+    
+    TNatReturnStatus status = KNatAsync;
+    
+    switch ( aEvent )
+    	{
+    	case MNATFWConnectivityObserver::ELocalCandidateFound:
+    		{
+    		iLocalCandidates.AppendL( reinterpret_cast<CNATFWCandidate*>(aData) );
+    		break;
+    		}
+    	
+    	case MNATFWConnectivityObserver::ECandidatePairFound:
+    		{
+    	    delete iCandidatePair;
+    	    iCandidatePair = reinterpret_cast<CNATFWCandidatePair*>(aData);
+    		break;
+    		}
+    	
+        case MNATFWConnectivityObserver::EReceivingActivated:
+            {
+            status = HandleReceivingActivated( aError );
+            break;
+            }
+        
+        case MNATFWConnectivityObserver::ESendingActivated:
+            {
+            status = HandleSendingActivated( aError );
+            break;
+            }
+        
+        case MNATFWConnectivityObserver::EFetchingCompleted:
+            {
+            status = HandleFetchingCompleted( aError );
+            break;
+            }
+        
+        case MNATFWConnectivityObserver::EConnChecksCompleted:
+            {
+            status = HandleConnChecksCompleted( aError );
+            break;
+            }
+        
+        case MNATFWConnectivityObserver::EReceivingDeactivated:
+            {
+            status = HandleReceivingDeActivated( aError );
+            break;
+            }
+        
+        case MNATFWConnectivityObserver::ESendingDeactivated:
+            {
+            status = HandleSendingDeActivated( aError );
+            break;
+            }
+        
+        case MNATFWConnectivityObserver::EGeneralError:
+        	{
+        	status = ErrorOccurred( aError );
+        	break;
+        	}
+        
+        case MNATFWConnectivityObserver::ESessionCreated:
+        default:
+            {
+            User::Leave( KErrNotReady );
+            }
+    	}
+    
+    NSPLOG_INT( "CNSPMediaStreamComponent::ControlMediaL(), Exit, status", status )
+    return status;
+	}
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::ResetAndDestroyCandidates
+// ---------------------------------------------------------------------------
+//
+void CNSPMediaStreamComponent::ResetAndDestroyCandidates()
+    {
+    iLocalCandidates.ResetAndDestroy();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::FetchCandidateL
+// ---------------------------------------------------------------------------
+//
+void CNSPMediaStreamComponent::FetchCandidateL()
+    {
+    iState->CheckStateL( CNSPNATFWAsyncState::ENATFWEventFetchCand );
+    
+    iController.FetchCandidateL( iSessionId, iStreamId, iAddrFamily );
+    iTimerTransactionId = iController.OrderTimeoutL( iSessionId, iStreamId,
+            MNATFWConnectivityObserver::EFetchingCompleted,
+            KNSPFetchCandTimerInMicros );
+    
+    iState->ChangeStateL( CNSPNATFWAsyncState::ENATFWEventFetchCand );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::FetchCandidatesL
+// ---------------------------------------------------------------------------
+//
+void CNSPMediaStreamComponent::FetchCandidatesL()
+    {
+    iState->CheckStateL( CNSPNATFWAsyncState::ENATFWEventFetchCand );
+    
+    iController.FetchCandidatesL( iSessionId,
+            iStreamId, iCollectionId, iComponentId, iAddrFamily );
+    iTimerTransactionId = iController.OrderTimeoutL( iSessionId, iStreamId,
+            MNATFWConnectivityObserver::EFetchingCompleted,
+            KNSPFetchCandTimerInMicros );
+    
+    iState->ChangeStateL( CNSPNATFWAsyncState::ENATFWEventFetchCand );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::PerformCandidateChecksL
+// ---------------------------------------------------------------------------
+//
+void CNSPMediaStreamComponent::PerformCandidateChecksL()
+    {
+    iState->ChangeStateL( CNSPNATFWAsyncState::ENATFWEventPerformChecks );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::ActivateL
+// ---------------------------------------------------------------------------
+//
+void CNSPMediaStreamComponent::ActivateL( const TDesC8& aAddress, TUint aPort )
+    {
+    iState->CheckStateL( CNSPNATFWAsyncState::ENATFWEventRecvAct );
+    iState->ChangeStateL( CNSPNATFWAsyncState::ENATFWEventRecvDeAct );
+    iState->ChangeStateL( CNSPNATFWAsyncState::ENATFWEventSendDeAct );
+    
+    iRemoteAddress.Close();
+    iRemoteAddress.Assign( aAddress.AllocL() );
+    iRemotePort = aPort;
+    
+    __ASSERT_ALWAYS( iLocalCandidates.Count(), User::Leave( KErrNotReady ) );
+    NATFWRECEIVING_L( *iLocalCandidates[0], EStreamingStateActive );
+    NATFWSENDING_L( *iLocalCandidates[0], EStreamingStateActive );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::ActivateL
+// ---------------------------------------------------------------------------
+//
+void CNSPMediaStreamComponent::ActivateL()
+    {
+    __ASSERT_ALWAYS( iCandidatePair, User::Leave( KErrNotReady ) );
+    
+    iState->CheckStateL( CNSPNATFWAsyncState::ENATFWEventRecvAct );    
+    iState->ChangeStateL( CNSPNATFWAsyncState::ENATFWEventRecvDeAct );
+    iState->ChangeStateL( CNSPNATFWAsyncState::ENATFWEventSendDeAct );
+    
+    iRemoteAddress.Close();
+    iRemoteAddress.Assign( iCandidatePair->RemoteCandidate().TransportDomainAddr().AllocL() );
+    iRemotePort = iCandidatePair->RemoteCandidate().TransportDomainPort();
+    
+    NATFWRECEIVING_L( iCandidatePair->LocalCandidate(), EStreamingStateActive );
+    NATFWSENDING_L( iCandidatePair->LocalCandidate(), EStreamingStateActive );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::DeActivateL
+// ---------------------------------------------------------------------------
+//
+void CNSPMediaStreamComponent::DeActivateL()
+    {
+    iState->CheckStateL( CNSPNATFWAsyncState::ENATFWEventRecvDeAct );
+    
+    __ASSERT_ALWAYS( iLocalCandidates.Count(), User::Leave( KErrNotReady ) );
+    NATFWRECEIVING_L( *iLocalCandidates[0], EStreamingStatePassive );
+    NATFWSENDING_L( *iLocalCandidates[0], EStreamingStatePassive );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::RemoteAddress
+// ---------------------------------------------------------------------------
+//
+const TDesC8& CNSPMediaStreamComponent::RemoteAddress() const
+    {
+    return iRemoteAddress;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::RemotePort
+// ---------------------------------------------------------------------------
+//
+TUint CNSPMediaStreamComponent::RemotePort() const
+    {
+    return iRemotePort;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::StreamId
+// ---------------------------------------------------------------------------
+//
+TUint CNSPMediaStreamComponent::StreamId() const
+    {
+    return iStreamId;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::ComponentId
+// ---------------------------------------------------------------------------
+//
+TUint CNSPMediaStreamComponent::ComponentId() const
+    {
+    return iComponentId;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::LocalCandidates
+// ---------------------------------------------------------------------------
+//
+RPointerArray<CNATFWCandidate>& CNSPMediaStreamComponent::LocalCandidates()
+    {
+    return iLocalCandidates;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::IceLocalCandidateL
+// ---------------------------------------------------------------------------
+//
+const CNATFWCandidate& CNSPMediaStreamComponent::IceLocalCandidateL()
+    {
+    __ASSERT_ALWAYS( iCandidatePair, User::Leave( KErrNotReady ) );
+    return iCandidatePair->LocalCandidate();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::IceRemoteCandidateL
+// ---------------------------------------------------------------------------
+//
+const CNATFWCandidate& CNSPMediaStreamComponent::IceRemoteCandidateL()
+    {
+    __ASSERT_ALWAYS( iCandidatePair, User::Leave( KErrNotReady ) );
+    return iCandidatePair->RemoteCandidate();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::OutgoingAddress
+// ---------------------------------------------------------------------------
+//
+TInt CNSPMediaStreamComponent::OutgoingAddress( TDes8& aAddress, TUint& aPort ) const
+    {
+    TInetAddr address;
+    iWrapper->OutgoingAddr( address );
+    TRAPD( error, ConvertTInetAddrToTDes8AndTUintL( address, aAddress, aPort ) );
+    return error;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::SetCredentialsL
+// ---------------------------------------------------------------------------
+//
+void CNSPMediaStreamComponent::SetCredentialsL( const CNATFWCredentials& aCredentials )
+    {
+    iController.SetCredentialsL( iSessionId, iStreamId, aCredentials );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::AttachCandidateL
+// ---------------------------------------------------------------------------
+//
+TBool CNSPMediaStreamComponent::AttachCandidateL( CNATFWCandidate& aCandidate ) const
+    {
+    if ( aCandidate.ComponentId() == iComponentId )
+        {
+        aCandidate.SetStreamId( iStreamId );
+        return ETrue;
+        }
+    
+    return EFalse;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::HandleReceivingActivated
+// ---------------------------------------------------------------------------
+//
+TNatReturnStatus CNSPMediaStreamComponent::HandleReceivingActivated(
+        TInt aError )
+    {
+    TInt error = iState->CheckState( CNSPNATFWAsyncState::ENATFWEventRecvAct );
+    
+    if ( KErrNone == error && KErrNone == aError )
+        {
+        iState->ChangeState( CNSPNATFWAsyncState::ENATFWEventRecvAct );
+        return Continue();
+        }
+    else if ( KErrNone == aError )
+        {
+        return ErrorOccurred( error );
+        }
+    else
+        {
+        return ErrorOccurred( aError );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::HandleSendingActivated
+// ---------------------------------------------------------------------------
+//
+TNatReturnStatus CNSPMediaStreamComponent::HandleSendingActivated(
+        TInt aError )
+    {
+    TInt error = iState->CheckState( CNSPNATFWAsyncState::ENATFWEventSendAct );
+    
+    if ( KErrNone == error && KErrNone == aError )
+        {
+        iState->ChangeState( CNSPNATFWAsyncState::ENATFWEventSendAct );
+        return Continue();
+        }
+    else if ( KErrNone == aError )
+        {
+        return ErrorOccurred( error );
+        }
+    else
+        {
+        return ErrorOccurred( aError );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::HandleReceivingDeActivated
+// ---------------------------------------------------------------------------
+//
+TNatReturnStatus CNSPMediaStreamComponent::HandleReceivingDeActivated(
+        TInt aError )
+    {
+    TInt error = iState->CheckState( CNSPNATFWAsyncState::ENATFWEventRecvDeAct );
+    
+    if ( KErrNone == error && KErrNone == aError )
+        {
+        iState->ChangeState( CNSPNATFWAsyncState::ENATFWEventRecvDeAct );
+        return Continue();
+        }
+    else if ( KErrNone == aError )
+        {
+        return ErrorOccurred( error );
+        }
+    else
+        {
+        return ErrorOccurred( aError );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::HandleSendingDeActivated
+// ---------------------------------------------------------------------------
+//
+TNatReturnStatus CNSPMediaStreamComponent::HandleSendingDeActivated(
+        TInt aError )
+    {
+    TInt error = iState->CheckState( CNSPNATFWAsyncState::ENATFWEventSendDeAct );
+    
+    if ( KErrNone == error && KErrNone == aError )
+        {
+        iState->ChangeState( CNSPNATFWAsyncState::ENATFWEventSendDeAct );
+        return Continue();
+        }
+    else if ( KErrNone == aError )
+        {
+        return ErrorOccurred( error );
+        }
+    else
+        {
+        return ErrorOccurred( aError );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::HandleFetchingCompleted
+// ---------------------------------------------------------------------------
+//
+TNatReturnStatus CNSPMediaStreamComponent::HandleFetchingCompleted( TInt aError )
+    {
+    iController.Cancel( iTimerTransactionId );
+    
+    TNatReturnStatus status = 
+        ( KErrNone == aError ? Continue() : ErrorOccurred( aError ) );
+    
+    if ( iLocalCandidates.Count() )
+        {
+        const CNATFWCandidate& candidate = *iLocalCandidates[0];
+        
+        // local candidates are never in FQDN format
+        if ( candidate.Type() == CNATFWCandidate::EServerReflexive &&
+             candidate.Base().CmpAddr( candidate.TransportAddr() ) )
+            {
+            // we are not behind NAT, no need to proceed with NATFW
+            NSPLOG_STR( 
+                "CNSPMediaStreamComponent::HandleFetchingCompleted, NO NAT" )
+            status = KNatNonFatalErrorLimit;
+            }
+        }
+    
+    return status;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::HandleConnChecksCompleted
+// ---------------------------------------------------------------------------
+//
+TNatReturnStatus CNSPMediaStreamComponent::HandleConnChecksCompleted( TInt aError )
+    {
+    return ( KErrNone == aError ? Continue() : ErrorOccurred( aError ) );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::Continue
+// ---------------------------------------------------------------------------
+//
+TNatReturnStatus CNSPMediaStreamComponent::Continue()
+    {
+    return ( iState->Continue() ? KNatReady : KNatAsync );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStreamComponent::ErrorOccurred
+// ---------------------------------------------------------------------------
+//
+TNatReturnStatus CNSPMediaStreamComponent::ErrorOccurred( TInt aError )
+    {
+    NSPLOG_INT( "CNSPMediaStreamComponent::ErrorOccurred():", aError )
+    
+    return ( KErrTimedOut == aError ||
+    		 SuppressRtcpIcmp( aError ) ? Continue() : aError );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNSPMediaStream::SuppressRtcpIcmp
+// ---------------------------------------------------------------------------
+//
+TBool CNSPMediaStreamComponent::SuppressRtcpIcmp( TInt aError ) const
+	{
+	return ( KNSPRtcpComponentId == iComponentId && NSP_ICMP( aError ) );
+	}
+
+
+// end of file