natplugins/natpnatfwsdpprovider/src/nspcontroller.cpp
author vnuitven <>
Mon, 06 Sep 2010 19:02:58 +0530
branchrcs
changeset 51 a13dcee59a62
parent 0 1bce908db942
permissions -rw-r--r--
modifications in the copyright for these files

/*
* 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:  Controller class implementation
*
*/

#include <sdpdocument.h>
#include <random.h>
#include <centralrepository.h>
#include <unsafprotocolscrkeys.h>
#include <e32math.h>
#include <badesca.h>
#include "natfwconnectivityapi.h"
#include "natfwcandidate.h"
#include "natfwcandidatepair.h"
#include "nspsessionobserver.h"
#include "nspcontroller.h"
#include "nspsession.h"
#include "nspevents.h"
#include "nspactive.h"
#include "nspcontentparser.h"
#include "nspdefs.h"

// CONSTANTS
//_LIT8( KStun, "stun" );
//_LIT8( KTurn, "turn" );
_LIT8( KIce, "ice" );

_LIT8( KNSPCharStore,
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/" );
_LIT8( KNSPSingleDigit, "x" );

const TText8* const KComma = _S8( "," );
const TUint KCommaLength = 1;
const TText8* const KDot = _S8( "." );

const TUint KNSPSingleDigitLength = 1;
const TUint KNSPUsernameMinLength = 4;
const TUint KNSPPasswordMinLength = 22;
const TUint KNSPVariationLength = 4;
const TUint KDefaultUpdateSdpTimerValue = 10;

static TDesC8& TrimAll( HBufC8& aDes )
    {
    TPtr8 ptr( aDes.Des() );
    ptr.TrimAll();
    return aDes;
    }


// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// CNSPController::CNSPController
// ---------------------------------------------------------------------------
//
CNSPController::CNSPController()
    {    
    }


// ---------------------------------------------------------------------------
// CNSPController::ConstructL
// ---------------------------------------------------------------------------
//
void CNSPController::ConstructL()
    {
    NSPLOG_STR( "CNSPController::ConstructL(), Entry" )
    
    iInterface = CNATFWConnectivityApi::NewL();
    iInterface->RegisterObserverForEventsL(
        *this, MNATFWConnectivityObserver::EAllEvents );
    iContentParser = CNSPContentParser::NewL();
    iBase = Abs( static_cast<TInt>( Math::Random() ) );
    
    NSPLOG_STR( "CNSPController::ConstructL(), Exit" )
    }


// ---------------------------------------------------------------------------
// CNSPController::NewL
// ---------------------------------------------------------------------------
//
CNSPController* CNSPController::NewL()
    {
    CNSPController* self = CNSPController::NewLC();
    CleanupStack::Pop( self );
    return self;
    }


// ---------------------------------------------------------------------------
// CNSPController::NewLC
// ---------------------------------------------------------------------------
//
CNSPController* CNSPController::NewLC()
    {
    CNSPController* self = new ( ELeave ) CNSPController;
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }


// ---------------------------------------------------------------------------
// CNSPController::~CNSPController
// ---------------------------------------------------------------------------
//
CNSPController::~CNSPController()
    {
    NSPLOG_STR( "CNSPController::~CNSPController(), Entry" )
    
    iActiveObjects.ResetAndDestroy();
    iActiveObjects.Close();    
    iSessionArray.ResetAndDestroy();
    iSessionArray.Close();
    iClosingSessionArray.ResetAndDestroy();
    iClosingSessionArray.Close();
    delete iContentParser;
    if ( iInterface )
        {
        iInterface->UnregisterObserverForEvents(
            *this, MNATFWConnectivityObserver::EAllEvents );
        }
    delete iInterface;
    
    NSPLOG_STR( "CNSPController::~CNSPController(), Exit" )
    }


// ---------------------------------------------------------------------------
// CNSPController::EventOccured
// ---------------------------------------------------------------------------
//
void CNSPController::EventOccured( TUint aSessionId, TUint aStreamId,
        TNATFWConnectivityEvent aEvent, TInt aError, TAny* aEventData )
    {
    NSPLOG_STR( "CNSPController::EventOccured(), Entry" )
    
    TInt index = FindSession( aSessionId );
    
    if ( KErrNotFound != index )
        {
        TEventReturnStatus status = iSessionArray[index]->EventOccured(
        		aStreamId, aEvent, aError, aEventData );
        Callback( *iSessionArray[index], status );
        }
    else
        {
        index = FindClosingSession( aSessionId );
        
        if ( KErrNotFound != index )
            {
            TEventReturnStatus status = iClosingSessionArray[index]->EventOccured(
                    aStreamId, aEvent, aError, aEventData );
            
            if ( NSP_DELETE( status.iStatus ) || NSP_ERROR( status.iStatus ) )
                {
                delete iClosingSessionArray[index];
                iClosingSessionArray.Remove(index);
                iClosingSessionArray.Close();
                RemoveActiveObjects( aSessionId );
                }
            }
        else
            {
            NSPLOG_STR( "CNSPController::EventOccured(), KErrNotFound" )
            NSPLOG_INT( "CNSPController::EventOccured(), error:", aError )
            }
        }
    
    NSPLOG_STR( "CNSPController::EventOccured(), Exit" )
    }


// ---------------------------------------------------------------------------
// CNSPController::ContentParser
// ---------------------------------------------------------------------------
//
const CNSPContentParser& CNSPController::ContentParser()
    {
    return (*iContentParser);
    }


// ---------------------------------------------------------------------------
// CNSPController::CreateSessionL
// ---------------------------------------------------------------------------
//
TUint CNSPController::CreateSessionL( TUint32 aIapId, const TDesC8& aDomain )
    {
    return iInterface->CreateSessionL( aIapId, aDomain );
    }


// ---------------------------------------------------------------------------
// CNSPController::LoadPluginL
// ---------------------------------------------------------------------------
//
void CNSPController::LoadPluginL( TUint aSessionId, const CDesC8Array& aPlugins,
        TInt& aPluginIndex )
    {
    iInterface->LoadPluginL( aSessionId, aPlugins, aPluginIndex );
    }


// ---------------------------------------------------------------------------
// CNSPController::CreateStreamL
// ---------------------------------------------------------------------------
//
TUint CNSPController::CreateStreamL( TUint aSessionId, TUint aProtocol, TInt aQoS )
    {
    return iInterface->CreateStreamL( aSessionId, aProtocol, aQoS );
    }


// ---------------------------------------------------------------------------
// CNSPController::CreateWrapperL
// ---------------------------------------------------------------------------
//
MNATFWSocketMediaConnWrapper& CNSPController::CreateWrapperL( 
        TUint aSessionId, TUint aStreamId )
    {
    return iInterface->CreateWrapperL( aSessionId, aStreamId );
    }


// ---------------------------------------------------------------------------
// CNSPController::FetchCandidateL
// ---------------------------------------------------------------------------
//
void CNSPController::FetchCandidateL( TUint aSessionId, TUint aStreamId,
        TUint aAddrFamily )
    {
    iInterface->FetchCandidateL( aSessionId, aStreamId, aAddrFamily );
    }


// ---------------------------------------------------------------------------
// CNSPController::FetchCandidatesL
// ---------------------------------------------------------------------------
//
void CNSPController::FetchCandidatesL( TUint aSessionId, TUint aStreamId,
        TUint aCollectionId, TUint aComponentId, TUint aAddrFamily )
    {
    iInterface->FetchCandidatesL( aSessionId, aStreamId,
            aCollectionId, aComponentId, aAddrFamily );
    }


// ---------------------------------------------------------------------------
// CNSPController::SetReceivingStateL
// ---------------------------------------------------------------------------
//
void CNSPController::SetReceivingStateL( const CNATFWCandidate& aLocalCand,
        TNATFWStreamingState aState )
    {
    iInterface->SetReceivingStateL( aLocalCand, aState );
    }


// ---------------------------------------------------------------------------
// CNSPController::SetSendingStateL
// ---------------------------------------------------------------------------
//
void CNSPController::SetSendingStateL( const CNATFWCandidate& aLocalCand,
        TNATFWStreamingState aState, const TDesC8& aDestAddr, TUint aPort )
    {
    iInterface->SetSendingStateL( aLocalCand, aState, aDestAddr, aPort );
    }


// ---------------------------------------------------------------------------
// CNSPController::SetRoleL
// ---------------------------------------------------------------------------
//
void CNSPController::SetRoleL( TUint aSessionId, TNATFWIceRole aRole )
    {
    iInterface->SetRoleL( aSessionId, aRole );
    }


// ---------------------------------------------------------------------------
// CNSPController::SetCredentialsL
// ---------------------------------------------------------------------------
//
void CNSPController::SetCredentialsL( TUint aSessionId, TUint aStreamId,
        const CNATFWCredentials& aCredentials )
    {
    CNATFWCandidate* dummyCand = CNATFWCandidate::NewLC();
    dummyCand->SetSessionId( aSessionId );
    dummyCand->SetStreamId( aStreamId );
    iInterface->SetCredentialsL( *dummyCand, aCredentials );
    CleanupStack::PopAndDestroy( dummyCand );
    }


// ---------------------------------------------------------------------------
// CNSPController::PerformCandidateChecksL
// ---------------------------------------------------------------------------
//
void CNSPController::PerformCandidateChecksL( TUint aSessionId,
        RPointerArray<CNATFWCandidate>& aRemoteCandidates )
    {
    iInterface->PerformConnectivityChecksL( aSessionId, aRemoteCandidates );
    }


// ---------------------------------------------------------------------------
// CNSPController::UpdateIceProcessingL
// ---------------------------------------------------------------------------
//
void CNSPController::UpdateIceProcessingL( TUint aSessionId,
        RPointerArray<CNATFWCandidate>& aNewRemoteCands )
    {
    iInterface->UpdateIceProcessingL( aSessionId, aNewRemoteCands );
    }


// ---------------------------------------------------------------------------
// CNSPController::CloseStreamL
// ---------------------------------------------------------------------------
//
void CNSPController::CloseStreamL( TUint aSessionId, TUint aStreamId )
    {
    iInterface->CloseStreamL( aSessionId, aStreamId );
    }


// ---------------------------------------------------------------------------
// CNSPController::CloseSessionL
// ---------------------------------------------------------------------------
//
void CNSPController::CloseSessionL( TUint aSessionId )
    {
    iInterface->CloseSessionL( aSessionId );
    }


// ---------------------------------------------------------------------------
// CNSPController::CreateUniqueId
// ---------------------------------------------------------------------------
//
TUint CNSPController::CreateUniqueId()
    {
    return (iBase++);
    }


// ---------------------------------------------------------------------------
// CNSPController::OrderTimeoutL
// ---------------------------------------------------------------------------
//
TUint CNSPController::OrderTimeoutL( TUint aSessionId, TUint aStreamId,
        MNATFWConnectivityObserver::TNATFWConnectivityEvent aEvent,
        TUint aTimerInMicroSeconds )
    {
    CNSPActive* callback = NULL;
    const TInt index = FindSession( aSessionId );
    const TUint transactionId = CreateUniqueId();
    
    if ( KErrNotFound != index )
        {
        TRAPD( error, callback = CNSPActive::NewL( *this,
                aSessionId, aStreamId, transactionId, aEvent,
                aTimerInMicroSeconds, NULL ) );
        
        User::LeaveIfError( error );
        error = iActiveObjects.Append( callback );
        
        if ( KErrNone != error )
            {
            delete callback;
            User::LeaveIfError( error );
            }
        }
    else
        {
        User::Leave( KErrNotFound );
        }
    
    return transactionId;
    }


// ---------------------------------------------------------------------------
// CNSPController::OrderUpdateSdpL
// ---------------------------------------------------------------------------
//
TUint CNSPController::OrderUpdateSdpL( TUint aSessionId, CSdpDocument* aDoc )
    {
    CNSPActive* callback = NULL;
    const TInt index = FindSession( aSessionId );
    const TUint transactionId = CreateUniqueId();
    
    if ( KErrNotFound != index )
        {
        CleanupStack::PushL( aDoc );
        callback = CNSPActive::NewL( *this,
                aSessionId, (TUint) KErrNone, transactionId,
                (MNATFWConnectivityObserver::TNATFWConnectivityEvent) KErrNone,
                KDefaultUpdateSdpTimerValue, aDoc );
        CleanupStack::Pop( aDoc );
        CleanupStack::PushL( callback );
        
        iActiveObjects.AppendL( callback );
        CleanupStack::Pop( callback );
        }
    else
        {
        User::Leave( KErrNotFound );
        }
    
    return transactionId;
    }


// ---------------------------------------------------------------------------
// CNSPController::Cancel
// ---------------------------------------------------------------------------
//
void CNSPController::Cancel( TUint aTransactionId )
    {
    const TInt index = FindActiveObject( aTransactionId );
    
    if ( KErrNotFound != index )
        {
        iActiveObjects[index]->Cancel();
        delete (iActiveObjects[index]);
        iActiveObjects.Remove(index);
        iActiveObjects.Compress();
        }
    }


// ---------------------------------------------------------------------------
// CNSPController::GenerateUsernameL
// ---------------------------------------------------------------------------
//
void CNSPController::GenerateUsernameL( TDes8& aUsername )
    {
    aUsername.Zero();
    
    TInt newlength = KNSPUsernameMinLength +
                     RandomByteL() % KNSPVariationLength;
    __ASSERT_ALWAYS( aUsername.MaxLength() >= newlength,
                     User::Leave( KErrArgument ) );
    
    for ( TInt index = 0; index < newlength; index++ )
        {
        aUsername.Append( KNSPCharStore()[
                RandomByteL() % KNSPCharStore().Length() ] );
        }
    }


// ---------------------------------------------------------------------------
// CNSPController::GeneratePasswordL
// ---------------------------------------------------------------------------
//
void CNSPController::GeneratePasswordL( TDes8& aPassword )
    {
    aPassword.Zero();
    
    TInt newlength = KNSPPasswordMinLength +
                     RandomByteL() % KNSPVariationLength;    
    __ASSERT_ALWAYS( aPassword.MaxLength() >= newlength,
                     User::Leave( KErrArgument ) );
    
    for ( TInt index = 0; index < newlength; index++ )
        {
        aPassword.Append( KNSPCharStore()[
                RandomByteL() % KNSPCharStore().Length() ] );
        }
    }


// ---------------------------------------------------------------------------
// CNSPController::NewSessionL
// ---------------------------------------------------------------------------
//
TUint CNSPController::NewSessionL( MNSPSessionObserver& aSessionObserver,
        TUint32 aIapId, const TDesC8& aDomain, TUint aProtocol )
    {
    NSPLOG_STR( "CNSPController::NewSessionL(), Entry" )
    
    CNSPSession* session = CNSPSession::NewLC( *this,
            aSessionObserver, aIapId, aDomain, aProtocol );
    session->SetUseIce( UseIceL( session->Plugins(), aDomain ) );
    User::LeaveIfError( iSessionArray.Append( session ) );
    CleanupStack::Pop( session );
    
    NSPLOG_STR( "CNSPController::NewSessionL(), Exit" )
    return session->SessionId();
    }


// ---------------------------------------------------------------------------
// CNSPController::CloseSessionL
// ---------------------------------------------------------------------------
//
void CNSPController::ClosingSessionL( TUint aSessionId )
    {
    const TInt index = FindSession( aSessionId );
    
    if ( KErrNotFound != index )
        {
        CNSPSession* session = iSessionArray[index];
        iSessionArray.Remove(index);
        iSessionArray.Compress();
        
        CleanupStack::PushL( session );
        TNatReturnStatus status = session->CloseSessionL();
        
        if ( KNatReady == status )
            {
            CleanupStack::Pop( session );
            delete session;
            }
        else
            {
            iClosingSessionArray.AppendL( session );// ownership changed
            CleanupStack::Pop( session );
            }
        }
    else
        {
        NSPLOG_STR( "CNSPController::CloseSessionL(), KErrNotFound" )
        User::Leave( KErrNotFound );
        }
    }


// ---------------------------------------------------------------------------
// CNSPController::FindSessionObject
// ---------------------------------------------------------------------------
//
CNSPSession& CNSPController::FindSessionObjectL( TUint aSessionId )
    {
    const TInt index = FindSession( aSessionId );
    
    if ( KErrNotFound == index )
        {
        NSPLOG_STR( "CNSPController::FindSessionObjectL(), KErrNotFound" )
        User::Leave( KErrNotFound );
        }
    
    return *iSessionArray[index];
    }


// ---------------------------------------------------------------------------
// CNSPController::FindSession
// ---------------------------------------------------------------------------
//
TInt CNSPController::FindSession( TUint aSessionId )
    {
    const TInt sessionCount( iSessionArray.Count() );
    for ( TInt index = 0; index < sessionCount; index++ )
        {
        if ( iSessionArray[index]->SessionId() == aSessionId )
            {
            return index;
            }
        }
    
    return KErrNotFound;
    }


// ---------------------------------------------------------------------------
// CNSPController::FindClosingSession
// ---------------------------------------------------------------------------
//
TInt CNSPController::FindClosingSession( TUint aSessionId )
    {
    const TInt sessionCount( iClosingSessionArray.Count() );
    for ( TInt index = 0; index < sessionCount; index++ )
        {
        if ( iClosingSessionArray[index]->SessionId() == aSessionId )
            {
            return index;
            }
        }
    
    return KErrNotFound;
    }


// ---------------------------------------------------------------------------
// CNSPController::FindActiveObject
// ---------------------------------------------------------------------------
//
TInt CNSPController::FindActiveObject( TUint aTransactionId )
    {
    if( aTransactionId != 0 )
        {
        const TInt activeObjectsCount( iActiveObjects.Count() );
        for ( TInt index = 0 ; index < activeObjectsCount; index++ )
            {
            if ( iActiveObjects[index]->TransactionId() == aTransactionId )
                {
                return index;
                }
            }
        }
    return KErrNotFound;
    }


// ---------------------------------------------------------------------------
// CNSPController::RemoveActiveObjects
// ---------------------------------------------------------------------------
//
void CNSPController::RemoveActiveObjects( TUint aSessionId )
    {
    const TInt activeObjectsCount( iActiveObjects.Count() );
    for ( TInt index = 0 ; index < activeObjectsCount; index++ )
        {
        if ( iActiveObjects[index]->SessionId() == aSessionId )
            {
            iActiveObjects[index]->Cancel();
            delete (iActiveObjects[index]);
            iActiveObjects.Remove(index);
            iActiveObjects.Compress();
            }
        }
    }


// ---------------------------------------------------------------------------
// CNSPController::RandomByteL
// ---------------------------------------------------------------------------
//
TUint8 CNSPController::RandomByteL() const
    {
    TBuf8< KNSPSingleDigitLength > buffer( KNSPSingleDigit );
    GenerateRandomBytesL( buffer ); // random byte received, as TDes8
    return static_cast< TUint8 >( buffer[0] );
    }


// ---------------------------------------------------------------------------
// CNSPController::UseIceL
// ---------------------------------------------------------------------------
//
TBool CNSPController::UseIceL( CDesC8Array& aArray, const TDesC8& aDomain ) const
    {
    CRepository* cenrep = CRepository::NewLC( KCRUidUNSAFProtocols );
    
    RArray<TUint32> keys;
    CleanupClosePushL( keys );
    
    User::LeaveIfError( cenrep->FindEqL( KUNSAFProtocolsDomainMask,
            KUNSAFProtocolsFieldTypeMask, aDomain, keys ) );
    __ASSERT_ALWAYS( keys.Count(), User::Leave( KErrNotFound ) );
    
    TUint32 currentDomainKey = KErrNone;
    currentDomainKey = KUNSAFProtocolsDomainMask^keys[0];
    currentDomainKey |= KUNSAFProtocolsUsedNATProtocolMask;
    
    TBuf8<1> tmp;
    TInt actualLength( 0 );
    cenrep->Get( currentDomainKey, tmp, actualLength ); // ret KErrOverFlow
    
    if ( 0 < actualLength )
        {
        HBufC8* protocol = HBufC8::NewLC( actualLength );
        TPtr8 ptr( protocol->Des() );
        User::LeaveIfError( cenrep->Get( currentDomainKey, ptr ) );
        ReplaceArrayL( aArray, protocol->Des() ); // leave if empty
        CleanupStack::PopAndDestroy( protocol );
        }
    else
        {
        User::Leave( KErrNotFound );
        }
    
    CleanupStack::PopAndDestroy(); // keys
    CleanupStack::PopAndDestroy( cenrep );
    
    return IsIce( aArray.MdcaPoint( 0 ) );
    }


// ---------------------------------------------------------------------------
// CNSPController::ReplaceArrayL
// ---------------------------------------------------------------------------
//
void CNSPController::ReplaceArrayL( CDesC8Array& aDesArray,
                                                const TDesC8& aString ) const
    {
    aDesArray.Reset();
    TPtrC8 ptr( TrimAll( *( aString.AllocLC() ) ) );
    
    while ( ptr.Length() )
        {
        const TInt length = ptr.Length();
        const TInt index = ptr.Find( TPtrC8( KComma ) );
        const TInt left = KErrNotFound != index ? index : length;
        const TInt right = ( length - KCommaLength ) - left;
        aDesArray.AppendL( TrimAll( *( ptr.Left( left ).AllocLC() ) ) );
        CleanupStack::PopAndDestroy();
        ptr.Set( ptr.Right( 0 < right ? right : 0 ) );
        }
    
    CleanupStack::PopAndDestroy();
    User::LeaveIfError( aDesArray.Count() ? KErrNone : KErrArgument );
    }


// ---------------------------------------------------------------------------
// CNSPController::RemoveIce
// ---------------------------------------------------------------------------
//
void CNSPController::RemoveIce( CDesC8Array& aDesArray ) const
    {
    for ( TInt index = 0; index < aDesArray.MdcaCount(); )
        {
        if ( IsIce( aDesArray.MdcaPoint( index ) ) )
            {
            aDesArray.Delete( index );
            aDesArray.Compress();
            }
        else
            {
            index++;
            }
        }
    }


// ---------------------------------------------------------------------------
// CNSPController::IsIce
// ---------------------------------------------------------------------------
//
TBool CNSPController::IsIce( const TDesC8& aProtocol ) const
    {
    TInt index = aProtocol.Find( TPtrC8( KDot ) );
    
    if ( KErrNotFound !=  index )
        {
        const TInt right = ( aProtocol.Length() - index ) - KCommaLength;
        TPtrC8 ptr( aProtocol.Right( 0 < right ? right : 0 ) );
        return ( !ptr.CompareF( KIce() ) ? ETrue : EFalse );
        }
    else
        {
        return EFalse;
        }
    }


// ---------------------------------------------------------------------------
// CNSPController::Callback
// ---------------------------------------------------------------------------
//
void CNSPController::Callback( const CNSPSession& aSession,
                                        TEventReturnStatus& aCallback ) const
	{
	switch ( aCallback.iType )
		{
		case TEventReturnStatus::ENone:
			{
			// NOP
			break;
			}
		
		case TEventReturnStatus::EInitialized:
			{
			ExecuteInitialized( aSession );
			break;
			}
		
		case TEventReturnStatus::EOfferReady:
			{
			ExecuteOfferReady( aSession, aCallback.iOffer );
			break;
			}
		
		case TEventReturnStatus::EAnswerReady:
			{
			ExecuteAnswerReady( aSession, aCallback.iAnswer );
			break;
			}
		
		case TEventReturnStatus::EUpdateSdp:
			{
			ExecuteUpdateSdp( aSession, aCallback.iOffer );
			break;
			}
		
		case TEventReturnStatus::EError:
			{
            ExecuteErrorOccurred( aSession, aCallback.iStatus );
			break;
			}
		
		default:
			{
			// NOP
			}
		}
	}


// ---------------------------------------------------------------------------
// CNSPController::ExecuteInitialized
// ---------------------------------------------------------------------------
//
void CNSPController::ExecuteInitialized( const CNSPSession& aSession ) const
	{
	MNSPSessionObserver& observer = aSession.SessionObserver();
	TUint sessionId = aSession.SessionId();
	
	NSP_OUTPUT_INITIALIZED
	observer.Initialized( sessionId );
	}


// ---------------------------------------------------------------------------
// CNSPController::ExecuteOfferReady
// ---------------------------------------------------------------------------
//
void CNSPController::ExecuteOfferReady( const CNSPSession& aSession,
		CSdpDocument* aOffer ) const
	{
	MNSPSessionObserver& observer = aSession.SessionObserver();
	TUint sessionId = aSession.SessionId();
	
	if ( aOffer )
		{
		NSP_OUTPUT_OFFER( KNatReady, *aOffer )
		observer.OfferReady( sessionId, aOffer );
		}
	else
		{
		ExecuteErrorOccurred( aSession, KErrTotalLossOfPrecision );
		}
	}


// ---------------------------------------------------------------------------
// CNSPController::ExecuteAnswerReady
// ---------------------------------------------------------------------------
//
void CNSPController::ExecuteAnswerReady( const CNSPSession& aSession,
		CSdpDocument* aAnswer ) const
	{
	MNSPSessionObserver& observer = aSession.SessionObserver();
	TUint sessionId = aSession.SessionId();
	
	if ( aAnswer )
		{
		NSP_OUTPUT_ANSWER( KNatReady, *aAnswer )
		observer.AnswerReady( sessionId, aAnswer );
		}
	else
		{
		ExecuteErrorOccurred( aSession, KErrTotalLossOfPrecision );
		}
	}


// ---------------------------------------------------------------------------
// CNSPController::ExecuteUpdateSdp
// ---------------------------------------------------------------------------
//
void CNSPController::ExecuteUpdateSdp( const CNSPSession& aSession,
		CSdpDocument* aOffer ) const
	{
	MNSPSessionObserver& observer = aSession.SessionObserver();
	TUint sessionId = aSession.SessionId();
	
	if ( aOffer )
		{
		NSP_OUTPUT_UPDATESDP( KNatReady, *aOffer )
		observer.UpdateSdp( sessionId, aOffer );
		}
	else
		{
		ExecuteErrorOccurred( aSession, KErrTotalLossOfPrecision );
		}
	}


// ---------------------------------------------------------------------------
// CNSPController::ExecuteErrorOccurred
// ---------------------------------------------------------------------------
//
void CNSPController::ExecuteErrorOccurred(
        const CNSPSession& aSession, TInt aError ) const
	{
	MNSPSessionObserver& observer = aSession.SessionObserver();
	TUint sessionId = aSession.SessionId();
	
	NSP_OUTPUT_ERROR( aError )
	
	if ( KErrCommsLineFail == aError )
		{
		observer.IcmpErrorOccurred( sessionId, aError );
		}
	else
		{
		observer.ErrorOccurred( sessionId, aError );
		}
	}

// end of file