--- /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