natfw/natfwclient/src/natfwsession.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/natfw/natfwclient/src/natfwsession.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,834 @@
+/*
+* 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:   
+*
+*/
+
+
+
+
+#include <badesca.h>
+#include "natfwpluginapi.h"
+#include "mnatfwconnectivityobserver.h"
+#include "natfwcandidatepair.h"
+#include "natfwcandidate.h"
+#include "natfwsession.h"
+#include "natfwstream.h"
+#include "mnatfwregistrationcontroller.h"
+#include <cnatfwsettingsapi.h>
+#include "natfwclientlogs.h"
+#include "cncmconnectionmultiplexer.h"
+#include "cnatfwasynccallback.h"
+
+const TUint KSendingActivationsNeeded = 2;
+
+const TUint KReceivingActivationsNeeded = 2;
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::CNATFWSession
+// ---------------------------------------------------------------------------
+//
+CNATFWSession::CNATFWSession( CNcmConnectionMultiplexer& aMultiplexer,
+        MNATFWRegistrationController& aController,
+        CNatFwAsyncCallback& aAsyncCallback,
+        TUint32 aIapId )
+    :
+    iIapId( aIapId ),
+    iController( aController ),
+    iMultiplexer( aMultiplexer ),
+    iAsyncCallback( aAsyncCallback ),
+    iServerConnectionState( EConnectionUnspecified )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::ConstructL( const TDesC8& aDomain )
+    {
+    iDomain = aDomain.AllocL();
+    TUint startPort( 0 );
+    TUint endPort( 0 );
+
+    iNatSettings = CNATFWNatSettingsApi::NewL( aDomain );
+
+    iNatSettings->GetPortArea( startPort, endPort );
+
+    iSessionId = iMultiplexer.CreateSessionL( iIapId, startPort, endPort );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::NewL
+// ---------------------------------------------------------------------------
+//
+CNATFWSession* CNATFWSession::NewL( CNcmConnectionMultiplexer& aMultiplexer,
+        MNATFWRegistrationController& aController,
+        CNatFwAsyncCallback& aAsyncCallback,
+        const TDesC8& aDomain,
+        TUint32 aIapId )
+    {
+    CNATFWSession* self =
+        CNATFWSession::NewLC( aMultiplexer, aController, aAsyncCallback,
+            aDomain, aIapId );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::NewLC
+// ---------------------------------------------------------------------------
+//
+CNATFWSession* CNATFWSession::NewLC( CNcmConnectionMultiplexer& aMultiplexer,
+        MNATFWRegistrationController& aController,
+        CNatFwAsyncCallback& aAsyncCallback,
+        const TDesC8& aDomain,
+        TUint32 aIapId )
+    {
+    CNATFWSession* self = new ( ELeave ) CNATFWSession( aMultiplexer,
+        aController, aAsyncCallback, aIapId );
+    CleanupStack::PushL( self );
+    self->ConstructL( aDomain );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CNATFWSession::~CNATFWSession()
+    {
+    iSendingStatusCounts.Close();
+    iReceivingStatusCounts.Close();
+    iFetchCandidateQueue.Close();
+    iStreams.ResetAndDestroy();
+    delete iDomain;
+    delete iPlugin;
+    delete iNatSettings;
+
+    REComSession::FinalClose();
+
+    TInt err = KErrNone;
+    TRAP( err, iMultiplexer.RemoveSessionL( iSessionId ) );
+    __NATFWCLIENT_INT1("CNATFWSession::~CNATFWSession, ERR:", err )
+    }
+
+
+// Non-derived function
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::LoadPluginL()
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::LoadPluginL( const CDesC8Array& aPlugins,
+        TInt& aLoadedPluginInd )
+    {
+    __NATFWCLIENT("CNATFWSession::LoadPluginL")
+    __ASSERT_ALWAYS( aPlugins.Count(), User::Leave( KErrArgument ) );
+
+    CNATFWPluginApi::TNATFWPluginInitParams
+        initParams( *this, iMultiplexer, *iDomain, iIapId );
+
+    TInt error( KErrNotFound );
+    TInt count( aPlugins.Count() );
+    TInt index( 0 );
+
+    delete iPlugin;
+    iPlugin = NULL;
+
+    while ( !iPlugin && index < count )
+        {
+        TRAP( error, iPlugin =
+            CNATFWPluginApi::NewL( aPlugins[index], initParams ) );
+        index++;
+        }
+
+    TInt ind( iStreams.Count() );
+    while ( ind-- )
+        {
+        iStreams[ind]->SetProtocolPlugin( iPlugin );
+        }
+
+    User::LeaveIfError( error );
+    aLoadedPluginInd = --index;
+
+    RSocketServ* socketServ = NULL;
+    TName connectionName;
+
+    socketServ = iMultiplexer.GetSessionInfoL( iSessionId, connectionName );
+    iPlugin->ConnectServerL( *socketServ, connectionName );
+    iServerConnectionState = EConnectionInProgress;
+
+    __NATFWCLIENT("CNATFWSession::LoadPluginL Exit")
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::FetchCandidateL
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::FetchCandidateL( TUint aStreamId, TUint aAddrFamily )
+    {
+    __ASSERT_ALWAYS( iServerConnectionState != EConnectionUnspecified,
+        User::Leave( KErrNotReady ) );
+    __ASSERT_ALWAYS( iServerConnectionState != EConnectionFailed,
+        User::Leave( KErrNotReady ) );
+
+    if ( iServerConnectionState == EConnectionConnected )
+        {
+        StreamByIdL( aStreamId )->FetchCandidateL( aAddrFamily );
+        }
+    else
+        {
+        TFetchingData data( aStreamId, 0, 0, aAddrFamily, EFalse );
+        iFetchCandidateQueue.InsertL( data, 0 );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::FetchCandidatesL
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::FetchCandidatesL( TUint aStreamId, TUint aCollectionId,
+        TUint aComponentId, TUint aAddrFamily )
+    {
+    __ASSERT_ALWAYS( iServerConnectionState != EConnectionUnspecified,
+        User::Leave( KErrNotReady ) );
+    __ASSERT_ALWAYS( iServerConnectionState != EConnectionFailed,
+        User::Leave( KErrNotReady ) );
+
+    if ( iServerConnectionState == EConnectionConnected )
+        {
+        StreamByIdL( aStreamId )->FetchCandidatesL(
+            aCollectionId, aComponentId, aAddrFamily );
+        }
+    else
+        {
+        TFetchingData data( aStreamId, aCollectionId,
+            aComponentId, aAddrFamily, ETrue );
+
+        iFetchCandidateQueue.InsertL( data, 0 );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::SessionId
+// ---------------------------------------------------------------------------
+//
+TUint CNATFWSession::SessionId() const
+    {
+    __NATFWCLIENT("CNATFWSession::SessionId")
+
+    return iSessionId;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::CreateStreamL
+// ---------------------------------------------------------------------------
+//
+TUint CNATFWSession::CreateStreamL(
+        TUint aProtocol, TInt aQoS )
+    {
+    __NATFWCLIENT("CNATFWSession::CreateStreamL")
+
+    CNATFWStream* stream = CNATFWStream::NewL( iController, iMultiplexer,
+        iAsyncCallback, *this, aProtocol, aQoS );
+    CleanupStack::PushL( stream );
+
+    iStreams.AppendL( stream );
+    stream->SetProtocolPlugin( iPlugin );
+
+    CleanupStack::Pop( stream );
+    return stream->StreamId();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::SetRoleL
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::SetRoleL( TNATFWIceRole aRole )
+    {
+    __NATFWCLIENT("CNATFWSession::SetRoleL")
+
+    iPlugin->SetRoleL( aRole );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::PerformConnectivityChecksL
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::PerformConnectivityChecksL(
+        RPointerArray<CNATFWCandidate>& aRemoteCandidates )
+    {
+    __NATFWCLIENT("CNATFWSession::PerformConnectivityChecksL")
+
+    iPlugin->PerformConnectivityChecksL( aRemoteCandidates );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::UpdateIceProcessingL
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::UpdateIceProcessingL(
+        RPointerArray<CNATFWCandidatePair>& aPeerSelectedPairs )
+    {
+    iPlugin->UpdateIceProcessingL( aPeerSelectedPairs );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::UpdateIceProcessingL
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::UpdateIceProcessingL(
+        RPointerArray<CNATFWCandidate>& aRemoteCands )
+    {
+    iPlugin->UpdateIceProcessingL( aRemoteCands );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::CloseStream
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::CloseStreamL( TUint aStreamId )
+    {
+    __NATFWCLIENT("CNATFWSession::CloseStreamL")
+
+    CNATFWStream* stream = StreamByIdL( aStreamId );
+    iStreams.Remove( iStreams.FindL( stream ) );
+    delete stream;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::StreamById
+// ---------------------------------------------------------------------------
+//
+CNATFWStream* CNATFWSession::StreamById( TUint aStreamId )
+    {
+    __NATFWCLIENT("CNATFWSession::StreamById")
+
+    TInt ind( iStreams.Count() );
+
+    while ( ind-- )
+        {
+        if ( iStreams[ind]->StreamId() == aStreamId )
+            {
+            return iStreams[ind];
+            }
+        }
+
+    return NULL;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::StreamByIdL
+// ---------------------------------------------------------------------------
+//
+CNATFWStream* CNATFWSession::StreamByIdL( TUint aStreamId )
+    {
+    __NATFWCLIENT("CNATFWSession::StreamByIdL")
+
+    CNATFWStream* stream = StreamById( aStreamId );
+    if ( !stream )
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    return stream;
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class MNATFWPluginObserver.
+// CNATFWSession::Error
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::Error( const CNATFWPluginApi& /*aPlugin*/,
+        TUint aStreamId, TInt aErrorCode )
+    {
+    __NATFWCLIENT("CNATFWSession::Error")
+
+    DoNotify( aStreamId, MNATFWConnectivityObserver::EGeneralError,
+        aErrorCode, NULL );
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class MNATFWPluginObserver.
+// CNATFWSession::Notify
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::Notify( const CNATFWPluginApi& /*aPlugin*/,
+        TUint aStreamId, TNATFWPluginEvent aEvent, TInt aErrCode )
+    {
+    __NATFWCLIENT("CNATFWSession::Notify")
+
+    // Activation notify must be waited from both plugin
+    // and mediastream before notifying NATFW client
+
+    switch ( aEvent )
+        {
+        case MNATFWPluginObserver::EServerConnected:
+            {
+            __NATFWCLIENT_INT1(
+                "CNATFWSession::Notify EServerConnected, ERR:", aErrCode )
+
+            if ( KErrNone != aErrCode )
+                {
+                iServerConnectionState = EConnectionFailed;
+                }
+            else
+                {
+                iServerConnectionState = EConnectionConnected;
+                }
+            HandleQueuedItems();
+            }
+            break;
+
+        case MNATFWPluginObserver::ESendingActivated:
+            {
+            __NATFWCLIENT_INT1(
+                "CNATFWSession::Notify ESendingActivated, ERR:", aErrCode )
+
+            TInt index = iSendingStatusCounts.Count() - 1;
+            TInt foundStreamInd( KErrNotFound );
+
+            while ( 0 <= index && KErrNotFound == foundStreamInd )
+                {
+                if ( aStreamId == iSendingStatusCounts[index].iStreamId )
+                    {
+                    foundStreamInd = index;
+
+                    if ( KErrNone != aErrCode )
+                        {
+                        iSendingStatusCounts[foundStreamInd].iErrorOccurred
+                            = ETrue;
+                        }
+
+                    iSendingStatusCounts[foundStreamInd].iActivatedCount++;
+                    }
+
+                index--;
+                }
+
+            if ( KErrNotFound != foundStreamInd )
+                {
+                if ( KSendingActivationsNeeded ==
+                    iSendingStatusCounts[foundStreamInd].iActivatedCount )
+                    {
+                    // The second notify for current stream's sending
+                    // activation has occurred so NATFW Stream can be
+                    // notified
+                    CNATFWStream* stream = StreamById( aStreamId );
+                    if ( stream )
+                        {
+                        if ( iSendingStatusCounts[foundStreamInd].
+                            iErrorOccurred )
+                            {
+                            // Reset the error occurred flag
+                            iSendingStatusCounts[foundStreamInd].iErrorOccurred
+                                = EFalse;
+                            // Do notification with error code
+                            stream->Notify( iSessionId, aStreamId,
+                                MNcmConnectionMultiplexerObserver::
+                                    ESendingActivated, KErrGeneral );
+                            }
+                        else
+                            {
+                            stream->Notify( iSessionId, aStreamId,
+                                MNcmConnectionMultiplexerObserver::
+                                    ESendingActivated, KErrNone );
+                            }
+                        }
+                    }
+                }
+            else
+                {
+                // The first notify for stream's sending activation has
+                // occurred so store stream's status data in array
+                TStatusCounter sendingActivated;
+                sendingActivated.iActivatedCount++;
+                sendingActivated.iStreamId = aStreamId;
+
+                if ( KErrNone != aErrCode )
+                    {
+                    sendingActivated.iErrorOccurred = ETrue;
+                    }
+
+                iSendingStatusCounts.Append( sendingActivated );
+                }
+            }
+            break;
+
+        case MNATFWPluginObserver::ESendingDeactivated:
+            {
+            __NATFWCLIENT_INT1(
+                "CNATFWSession::Notify ESendingDeactivated, ERR:", aErrCode )
+
+            TInt index = iSendingStatusCounts.Count() - 1;
+            TInt foundStreamInd( KErrNotFound );
+
+            while ( 0 <= index && KErrNotFound == foundStreamInd )
+                {
+                if ( aStreamId == iSendingStatusCounts[index].iStreamId &&
+                    iSendingStatusCounts[index].iActivatedCount != 0 )
+                    {
+                    foundStreamInd = index;
+
+                    if ( aErrCode != KErrNone )
+                        {
+                        iSendingStatusCounts[foundStreamInd].iErrorOccurred
+                            = ETrue;
+                        }
+
+                    iSendingStatusCounts[foundStreamInd].iActivatedCount--;
+                    }
+
+                index--;
+                }
+
+            if ( KErrNotFound != foundStreamInd )
+                {
+                if ( 0 == iSendingStatusCounts[foundStreamInd].
+                    iActivatedCount )
+                    {
+                    CNATFWStream* stream = StreamById( aStreamId );
+                    if ( stream )
+                        {
+                        if ( iSendingStatusCounts[foundStreamInd].
+                            iErrorOccurred )
+                            {
+                            // Reset the error occurred flag
+                            iSendingStatusCounts[foundStreamInd].iErrorOccurred
+                                = EFalse;
+                            // Do notification with error code
+                            stream->Notify( iSessionId, aStreamId,
+                                MNcmConnectionMultiplexerObserver::
+                                    ESendingDeactivated, KErrGeneral );
+                            }
+                        else
+                            {
+                            stream->Notify( iSessionId, aStreamId,
+                                MNcmConnectionMultiplexerObserver::
+                                    ESendingDeactivated, KErrNone );
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+
+        case MNATFWPluginObserver::EReceivingActivated:
+            {
+            __NATFWCLIENT_INT1(
+                "CNATFWSession::Notify EReceivingActivated, ERR:", aErrCode )
+
+            TInt index = iReceivingStatusCounts.Count() - 1;
+            TInt foundStreamInd( KErrNotFound );
+
+            while ( 0 <= index && KErrNotFound == foundStreamInd )
+                {
+                if ( aStreamId == iReceivingStatusCounts[index].iStreamId )
+                    {
+                    foundStreamInd = index;
+
+                    if ( KErrNone != aErrCode )
+                        {
+                        iReceivingStatusCounts[foundStreamInd].iErrorOccurred
+                            = ETrue;
+                        }
+
+                    iReceivingStatusCounts[foundStreamInd].iActivatedCount++;
+                    }
+
+                index--;
+                }
+
+            if ( KErrNotFound != foundStreamInd )
+                {
+                if ( KReceivingActivationsNeeded ==
+                    iReceivingStatusCounts[foundStreamInd].iActivatedCount )
+                    {
+                    // The second notify for current stream's receiving
+                    // activation has occurred so NATFW Stream can be
+                    // notified
+                    CNATFWStream* stream = StreamById( aStreamId );
+                    if ( stream )
+                        {
+                        if ( iReceivingStatusCounts[foundStreamInd].
+                            iErrorOccurred )
+                            {
+                            // Reset the error occurred flag
+                            iReceivingStatusCounts[foundStreamInd].iErrorOccurred
+                                = EFalse;
+                            // Do notification with error code
+                            stream->Notify( iSessionId, aStreamId,
+                                MNcmConnectionMultiplexerObserver::
+                                    EReceivingActivated, KErrGeneral );
+                            }
+                        else
+                            {
+                            stream->Notify( iSessionId, aStreamId,
+                                MNcmConnectionMultiplexerObserver::
+                                    EReceivingActivated, KErrNone );
+                            }
+                        }
+                    }
+                }
+            else
+                {
+                // The first notify for stream's receiving activation has
+                // occurred so store stream's status data in array
+                TStatusCounter receivingActivated;
+                receivingActivated.iActivatedCount++;
+                receivingActivated.iStreamId = aStreamId;
+
+                if ( KErrNone != aErrCode )
+                    {
+                    receivingActivated.iErrorOccurred = ETrue;
+                    }
+
+                iReceivingStatusCounts.Append( receivingActivated );
+                }
+            }
+            break;
+
+        case MNATFWPluginObserver::EReceivingDeactivated:
+            {
+            __NATFWCLIENT_INT1(
+                "CNATFWSession::Notify EReceivingDeactivated, ERR:", aErrCode )
+
+            TInt index = iReceivingStatusCounts.Count() - 1;
+            TInt foundStreamInd( KErrNotFound );
+
+            while ( 0 <= index && KErrNotFound == foundStreamInd )
+                {
+                if ( aStreamId == iReceivingStatusCounts[index].iStreamId &&
+                    iReceivingStatusCounts[index].iActivatedCount != 0 )
+                    {
+                    foundStreamInd = index;
+
+                    if ( aErrCode != KErrNone )
+                        {
+                        iReceivingStatusCounts[foundStreamInd].iErrorOccurred
+                            = ETrue;
+                        }
+
+                    iReceivingStatusCounts[foundStreamInd].iActivatedCount--;
+                    }
+
+                index--;
+                }
+
+            if ( KErrNotFound != foundStreamInd )
+                {
+                if ( 0 == iReceivingStatusCounts[foundStreamInd].
+                    iActivatedCount )
+                    {
+                    CNATFWStream* stream = StreamById( aStreamId );
+                    if ( stream )
+                        {
+                        if ( iReceivingStatusCounts[foundStreamInd].
+                            iErrorOccurred )
+                            {
+                            // Reset the error occurred flag
+                            iReceivingStatusCounts[foundStreamInd].iErrorOccurred
+                                = EFalse;
+                            // Do notification with error code
+                            stream->Notify( iSessionId, aStreamId,
+                                MNcmConnectionMultiplexerObserver::
+                                    EReceivingDeactivated, KErrGeneral );
+                            }
+                        else
+                            {
+                            stream->Notify( iSessionId, aStreamId,
+                                MNcmConnectionMultiplexerObserver::
+                                    EReceivingDeactivated, KErrNone );
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+
+        case MNATFWPluginObserver::EFetchingCompleted:
+            {
+            __NATFWCLIENT_INT1(
+                "CNATFWSession::Notify EFetchingCompleted, ERR:", aErrCode )
+
+            DoNotify( aStreamId, MNATFWConnectivityObserver::EFetchingCompleted,
+                aErrCode, NULL );
+            }
+            break;
+
+        case MNATFWPluginObserver::EConnChecksCompleted:
+            {
+            __NATFWCLIENT_INT1(
+                "CNATFWSession::Notify EConnChecksCompleted, ERR:", aErrCode )
+
+            DoNotify( aStreamId, MNATFWConnectivityObserver::EConnChecksCompleted,
+                aErrCode, NULL );
+            }
+            break;
+
+        default:
+            {
+            __NATFWCLIENT("CNATFWSession::Notify DEFAULT")
+            ASSERT( EFalse );
+            }
+            break;
+        }
+
+    __NATFWCLIENT("CNATFWSession::Notify Exit")
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class MNATFWPluginObserver.
+// CNATFWSession::NewCandidatePairFound
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::NewCandidatePairFound(
+        const CNATFWPluginApi& /*aPlugin*/,
+        CNATFWCandidatePair* aCandidatePair )
+    {
+    __NATFWCLIENT("CNATFWSession::NewCandidatePairFound")
+
+    if ( aCandidatePair )
+        {
+        const_cast<CNATFWCandidate&>(
+            aCandidatePair->RemoteCandidate() ).SetSessionId( iSessionId );
+        const_cast<CNATFWCandidate&>(
+            aCandidatePair->LocalCandidate() ).SetSessionId( iSessionId );
+        DoNotify( aCandidatePair->LocalCandidate().StreamId(), 
+            MNATFWConnectivityObserver::ECandidatePairFound,
+            KErrNone, aCandidatePair );
+        }
+    else
+        {
+        __NATFWCLIENT("CNATFWSession::NewCandidatePairFound - NULL POINTER")
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class MNATFWPluginObserver.
+// CNATFWSession::NewLocalCandidateFound
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::NewLocalCandidateFound(
+        const CNATFWPluginApi& /*aPlugin*/,
+        CNATFWCandidate* aCandidate )
+    {
+    __NATFWCLIENT("CNATFWSession::NewLocalCandidateFound")
+
+    if ( aCandidate )
+        {
+        aCandidate->SetSessionId( iSessionId );
+        DoNotify( aCandidate->StreamId(), 
+            MNATFWConnectivityObserver::ELocalCandidateFound,
+            KErrNone, aCandidate );
+        }
+    else
+        {
+        __NATFWCLIENT("CNATFWSession::NewLocalCandidateFound - NULL POINTER")
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::HandleQueuedItems
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::HandleQueuedItems()
+    {
+    __NATFWCLIENT("CNATFWSession::HandleQueuedItems - ENTRY")
+
+    TInt index( iFetchCandidateQueue.Count() - 1 );
+    TUint streamId( 0 );
+    TUint collectionId( 0 );
+    TUint componentId( 0 );
+    TUint addrFamily( KAFUnspec );
+    TBool iceSpecific( EFalse );
+
+    while ( 0 <= index )
+        {
+        streamId = iFetchCandidateQueue[index].iStreamId;
+        collectionId = iFetchCandidateQueue[index].iCollectionId;
+        componentId = iFetchCandidateQueue[index].iComponentId;
+        addrFamily = iFetchCandidateQueue[index].iAddrFamily;
+        iceSpecific = iFetchCandidateQueue[index].iICESpecific;
+        iFetchCandidateQueue.Remove( index );
+
+        CNATFWStream* str( NULL );
+        str = StreamById( streamId );
+
+        TInt error( KErrNone );
+        if ( str )
+            {
+            if( iceSpecific )
+                {
+                TRAP( error,
+                    str->FetchCandidatesL( 
+                        collectionId, componentId, addrFamily ) );
+                }
+            else
+                {
+                TRAP( error, str->FetchCandidateL( addrFamily ) );
+                }
+            }
+
+        if ( KErrNone != error )
+            {
+            DoNotify( streamId, MNATFWConnectivityObserver::EFetchingCompleted,
+                error, NULL );
+            }
+
+        --index;
+        }
+
+    __NATFWCLIENT("CNATFWSession::HandleQueuedItems - EXIT")
+    }
+
+
+// ---------------------------------------------------------------------------
+// CNATFWSession::DoNotify
+// ---------------------------------------------------------------------------
+//
+void CNATFWSession::DoNotify( TUint aStreamId,
+    MNATFWConnectivityObserver::TNATFWConnectivityEvent aEvent,
+    TInt aErrCode,
+    TAny* aEventData )
+    {
+    CNatFwCallbackInfo::TFunction func =
+        static_cast<CNatFwCallbackInfo::TFunction>( aEvent );
+
+    TRAP_IGNORE( iAsyncCallback.MakeCallbackL( iController, func,
+        iSessionId, aStreamId, aErrCode, aEventData ) )
+
+    }