localconnectivityservice/dun/utils/src/DunTransporter.cpp
branchRCL_3
changeset 40 52a167391590
parent 0 c3e98f10fcf4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/localconnectivityservice/dun/utils/src/DunTransporter.cpp	Wed Sep 01 12:20:40 2010 +0100
@@ -0,0 +1,891 @@
+/*
+* Copyright (c) 2006-2008 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:  Managing abstracted "channels" of network side communication
+*
+*/
+
+
+#include "DunTransUtils.h"
+#include "DunTransporter.h"
+#include "DunDataWaiter.h"
+#include "DunUpstream.h"
+#include "DunDownstream.h"
+#include "DunSignalCopy.h"
+#include "DunNoteHandler.h"
+#include "DunUtils.h"
+#include "DunDebug.h"
+#include "DunPlugin.h"
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CDunTransporter* CDunTransporter::NewL(
+    MDunPluginManager* aPluginManager,
+    TInt aNumOfMaxChannels )
+    {
+    CDunTransporter* self = new (ELeave) CDunTransporter( aPluginManager,
+                                                          aNumOfMaxChannels );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CDunTransporter::~CDunTransporter()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::~CDunTransporter()" )));
+    UnInitialize();
+    FTRACE(FPrint( _L("CDunTransporter::~CDunTransporter() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Number of allocated channels, is the same number as allocated and active
+// (non-waiting) channels
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::NumberOfAllocatedChannels()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::NumberOfAllocatedChannels()" )));
+    TInt i;
+    TInt allocChannels = 0;
+    TInt count = iChannelData.Count();
+    for ( i=0; i<count; i++ )
+        {
+        TDunChannelData& channelData = iChannelData[i];
+        if ( channelData.iChannelInUse )
+            {
+            allocChannels++;
+            }
+        }
+    FTRACE(FPrint( _L("CDunTransporter::NumberOfAllocatedChannels() complete" )));
+    return allocChannels;
+    }
+
+// ---------------------------------------------------------------------------
+// Number of waiting channels, is the same number as allocated and inactive
+// (waiting) channels
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::NumberOfWaitingChannels()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::NumberWaitingChannels()" )));
+    if ( !iInitialized )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::NumberWaitingChannels() complete" )));
+        return 0;
+        }
+    TInt waiters = iChanMan->NumberOfWaiters();
+    FTRACE(FPrint( _L("CDunTransporter::NumberWaitingChannels() complete" )));
+    return waiters;
+    }
+
+// ---------------------------------------------------------------------------
+// Gets the number of allocated channels by owner UID, is the same number as
+// allocated and active (non-waiting) channels
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::GetNumberOfAllocatedChannelsByUid(
+    TUid aOwnerUid )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::GetNumberOfAllocatedChannelsByUid()" )));
+    TInt i;
+    TInt allocChannels = 0;
+    TInt count = iChannelData.Count();
+    for ( i=0; i<count; i++ )
+        {
+        TDunChannelData& channelData = iChannelData[i];
+        if ( channelData.iOwnerUid==aOwnerUid && channelData.iChannelInUse )
+            {
+            allocChannels++;
+            }
+        }
+    FTRACE(FPrint( _L("CDunTransporter::GetNumberOfAllocatedChannelsByUid() complete" )));
+    return allocChannels;
+    }
+
+// ---------------------------------------------------------------------------
+// Gets the number of waiting channels by owner UID, is the same number as
+// allocated and inactive (waiting) channels
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::GetNumberOfWaitingChannelsByUid(
+    TUid aOwnerUid )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::GetNumberWaitingChannelsByUid()" )));
+    if ( !iInitialized )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::GetNumberWaitingChannelsByUid() complete" )));
+        return 0;
+        }
+    TInt waiters = iChanMan->GetNumberOfWaitersByUid( aOwnerUid );
+    FTRACE(FPrint( _L("CDunTransporter::GetNumberWaitingChannelsByUid() complete" )));
+    return waiters;
+    }
+
+// ---------------------------------------------------------------------------
+// Transporter's service advertisement status
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CDunTransporter::AdvertisementStatus()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::AdvertisementStatus()" )));
+    FTRACE(FPrint( _L("CDunTransporter::AdvertisementStatus() complete" )));
+    return iAdvertise;
+    }
+
+// ---------------------------------------------------------------------------
+// Creates a channel of communication between local media (aComm) and network
+// Local media object pointer also works as a connection ID for the
+// allocated channel
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::AllocateChannelL(
+    RComm* aComm,
+    TUid aOwnerUid,
+    const TDesC8& aName,
+    TBool aEnqueuedFail,
+    MDunBufferCorrection* aCorrection )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RComm)" )));
+
+    if ( !aComm )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (aComm not initialized!) complete" )));
+        User::Leave( KErrGeneral );
+        }
+
+    if ( !aComm->SubSessionHandle() )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RComm) (bad handle) complete" ) ));
+        User::Leave( KErrBadHandle );
+        }
+
+    TInt retTemp = InitializeOnDemand();
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RComm) (ERROR) complete" ) ));
+        User::Leave( retTemp );
+        }
+
+    iChanMan->AddConnWaiterL( aComm,
+                              aOwnerUid,
+                              aName,
+                              aEnqueuedFail,
+                              aCorrection );
+
+    FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RComm) complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Creates a channel of communication between local media (aSocket) and
+// network
+// Local media object pointer also works as a connection ID for the
+// allocated channel
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::AllocateChannelL(
+    RSocket* aSocket,
+    TUid aOwnerUid,
+    const TDesC8& aName,
+    TBool aEnqueuedFail,
+    TBool& aNoFreeChans )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RSocket)" )));
+
+    aNoFreeChans = EFalse;  // Initialize now if plugin didn't do it already
+
+    if ( !aSocket )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (aSocket not initialized!) complete" )));
+        User::Leave( KErrGeneral );
+        }
+    if ( !aSocket->SubSessionHandle() )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RSocket) (bad handle) complete" ) ));
+        User::Leave( KErrBadHandle );
+        }
+    TInt retTemp = InitializeOnDemand();
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RSocket) (ERROR) complete" )));
+        User::Leave( retTemp );
+        }
+    TInt firstFree = iUtility->InitializeFirstFreeChannel( aSocket );
+    if ( firstFree < 0 )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RSocket) (firstfree failed!) complete" ) ));
+        User::Leave( firstFree );
+        }
+    if ( firstFree >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RSocket) (firstfree failed!) complete" ) ));
+        User::Leave( KErrGeneral );
+        }
+    TInt bufferLength = KErrNotFound;
+    // bufferLength will be omitted (not needed to set to RSocket)
+    TRAPD( retTrap,
+        iUtility->DoAllocateChannelL(NULL, bufferLength, firstFree, NULL) );
+    if ( retTrap != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RSocket) trapped!" ) ));
+        UnInitializeOnDemand();  // remove unused initialized channel
+        if ( retTrap == KErrTooBig )
+            {
+            if ( aEnqueuedFail )
+                {
+                // Inform plugin enqueue request
+                iPluginManager->NotifyPluginEnqueueRequest( aOwnerUid );
+                }
+            aNoFreeChans = ETrue;  // Inform plugin about no free channels
+            FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RSocket) complete" )));
+            User::Leave( KErrTooBig );
+            }
+        FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RSocket) complete" )));
+        User::Leave( retTrap );
+        }
+    TDunChannelData& channelData = iChannelData[firstFree];
+    channelData.iSocket = aSocket;
+    channelData.iChannelName = HBufC8::NewMaxL( aName.Length() );
+    TPtr8 chanNamePtr = channelData.iChannelName->Des();
+    chanNamePtr.Copy( aName );
+    channelData.iUpstreamRW->SetMedia( aSocket, EDunMediaContextLocal );
+    channelData.iDownstreamRW->SetMedia( aSocket, EDunMediaContextLocal );
+    channelData.iOwnerUid = aOwnerUid;
+    // Channel now occupied
+    channelData.iChannelInUse = ETrue;
+
+    // Clear the queue, just to be sure
+    iPluginManager->NotifyPluginDequeueRequest( aOwnerUid );
+
+    FTRACE(FPrint( _L("CDunTransporter::AllocateChannel() (RSocket) complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Frees an allocated channel by local media (aComm) connection ID
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::FreeChannel( RComm* aComm )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RComm)" )));
+
+    TInt retTemp = CheckInitAndHandle( aComm );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RComm) (ERROR) complete" ) ));
+        return retTemp;
+        }
+
+    retTemp = iChanMan->RemoveConnWaiter( aComm );
+    if ( retTemp == KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RComm) complete" )));
+        return KErrNone;
+        }
+
+    // No waiter found, so try to find from channels
+    TInt mediaIndex = GetMediaIndex( aComm );
+    if ( mediaIndex < 0 )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RComm) (ERROR) complete" ) ));
+        return mediaIndex;
+        }
+
+    retTemp = iUtility->DoFreeChannel( mediaIndex );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RComm) (ERROR) complete" )));
+        return retTemp;
+        }
+    UnInitializeOnDemand();
+
+    FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RComm) complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Frees an allocated channel by local media (aSocket) connection ID
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::FreeChannel( RSocket* aSocket )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RSocket)" )));
+
+    TInt retTemp = CheckInitAndHandle( aSocket );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RSocket) (ERROR) complete" ) ));
+        return retTemp;
+        }
+
+    TInt mediaIndex = GetMediaIndex( aSocket );
+    if ( mediaIndex < 0 )
+        {
+        return mediaIndex;
+        }
+
+    retTemp = iUtility->DoFreeChannel( mediaIndex );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RSocket) (ERROR) complete" ) ));
+        return retTemp;
+        }
+    UnInitializeOnDemand();
+
+    FTRACE(FPrint( _L("CDunTransporter::FreeChannel() (RSocket) complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Issues transfer requests for all transfer objects by local media
+// (aComm) connection ID
+// This will cause the Transporter by be ready for transferring data
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::IssueTransferRequestsL( RComm* aComm )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::IssueTransferRequests() (RComm)" )));
+
+    User::LeaveIfError( CheckInitAndHandle( aComm ) );
+    TInt retTemp = iChanMan->IssueConnWaiterRequest( aComm );
+    if ( retTemp == KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::IssueTransferRequests() (RComm) complete" )));
+        return;
+        }
+
+    // No waiter found, so try to find from channels
+    TInt mediaIndex = GetMediaIndexL( aComm );
+    User::LeaveIfError( iUtility->DoIssueTransferRequests( mediaIndex ) );
+
+    FTRACE(FPrint( _L("CDunTransporter::IssueTransferRequests() (RComm) complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Issues transfer requests for all transfer objects by local media
+// (aSocket) connection ID
+// This will cause the Transporter by be ready for transferring data
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::IssueTransferRequestsL( RSocket* aSocket )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::IssueTransferRequests() (RSocket)" )));
+
+    User::LeaveIfError( CheckInitAndHandle( aSocket ) );
+    TInt mediaIndex = GetMediaIndexL( aSocket );
+    User::LeaveIfError( iUtility->DoIssueTransferRequests(mediaIndex) );
+
+    FTRACE(FPrint( _L("CDunTransporter::IssueTransferRequests() (RSocket) complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Stops transfers for all transfer objects by local media (aComm)
+// connection ID
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::StopTransfers( RComm* aComm )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RComm)" )));
+
+    TInt retTemp = CheckInitAndHandle( aComm );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RComm) (ERROR) complete" ) ));
+        return retTemp;
+        }
+
+    retTemp = iChanMan->StopConnWaiter( aComm );
+    if ( retTemp == KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RComm) complete" )));
+        return KErrNone;
+        }
+
+    // No waiter found, so try to find from channels
+    TInt mediaIndex = GetMediaIndex( aComm );
+    if ( mediaIndex < 0 )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RComm) (ERROR) complete" ) ));
+        return mediaIndex;
+        }
+
+    retTemp = iUtility->DoStopTransfers( mediaIndex );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RComm) (ERROR) complete" )));
+        return retTemp;
+        }
+
+    FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RComm) complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Stops transfers for all transfer objects by local media (aSocket)
+// connection ID
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::StopTransfers( RSocket* aSocket )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RSocket)" )));
+
+    TInt retTemp = CheckInitAndHandle( aSocket );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RSocket) (ERROR) complete" ) ));
+        return retTemp;
+        }
+
+    TInt mediaIndex = GetMediaIndex( aSocket );
+    if ( mediaIndex < 0 )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RSocket) (ERROR) complete" ) ));
+        return mediaIndex;
+        }
+
+    retTemp = iUtility->DoStopTransfers( mediaIndex );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RSocket) (ERROR) complete" )));
+        return retTemp;
+        }
+
+    FTRACE(FPrint( _L("CDunTransporter::StopTransfers() (RSocket) complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Adds connection monitor callback for either local media or network side
+// by connection ID
+// Callbacks will be called read/write error is detected during endpoint
+// operation
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::AddConnMonCallbackL( RComm* aComm,
+                                                    MDunConnMon* aCallback,
+                                                    TDunDirection aDirection,
+                                                    TBool /*aSignal*/ )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::AddConnMonCallbackL() (RComm)" )));
+
+    User::LeaveIfError( CheckInitAndHandle( aComm ) );
+    TInt retTemp = iChanMan->SaveWaiterConnMonCallbackL( aComm,
+                                                         aCallback,
+                                                         aDirection );
+    if ( retTemp == KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AddConnMonCallbackL() (RComm) complete" )));
+        return;
+        }
+
+    TInt mediaIndex = GetMediaIndexL( aComm );
+    User::LeaveIfError( iUtility->DoAddConnMonCallback( mediaIndex,
+                                                        aCallback,
+                                                        aDirection,
+                                                        NULL ));
+
+    FTRACE(FPrint( _L("CDunTransporter::AddConnMonCallbackL() (RComm) complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Adds connection monitor callback for either local media or network side
+// by connection ID
+// Callbacks will be called when line status switches to high or low
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::AddConnMonCallbackL( RSocket* aSocket,
+                                                    MDunConnMon* aCallback,
+                                                    TDunDirection aDirection,
+                                                    TBool aSignal )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::AddConnMonCallbackL() (RSocket)" )));
+
+    User::LeaveIfError( CheckInitAndHandle( aSocket ) );
+    TInt mediaIndex = GetMediaIndexL( aSocket );
+    User::LeaveIfError( iUtility->DoAddConnMonCallback( mediaIndex,
+                                                        aCallback,
+                                                        aDirection,
+                                                        aSignal ));
+
+    FTRACE(FPrint( _L("CDunTransporter::AddConnMonCallbackL() (RSocket) complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Adds error to consider as no error condition when doing any of the four
+// endpoint's read/writer operation
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::AddSkippedErrorL( TInt aError,
+                                                 RComm* aComm,
+                                                 TDunDirection aDirection )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::AddSkippedErrorL() (RComm)" )));
+
+    User::LeaveIfError( CheckInitAndHandle( aComm ) );
+    TInt retTemp = iChanMan->SaveWaiterSkippedErrorL( aError,
+                                                      aComm,
+                                                      aDirection );
+    if ( retTemp == KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::AddSkippedErrorL() (RComm) complete" )));
+        return;
+        }
+
+    TInt mediaIndex = GetMediaIndexL( aComm );
+    User::LeaveIfError( iUtility->DoAddSkippedError( mediaIndex,
+                                                     aError,
+                                                     aDirection ));
+
+    FTRACE(FPrint( _L("CDunTransporter::AddSkippedErrorL() (RComm) complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Adds error to consider as no error condition when doing any of the four
+// endpoint's read/writer operation
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::AddSkippedErrorL( TInt aError,
+                                                 RSocket* aSocket,
+                                                 TDunDirection aDirection )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::AddSkippedErrorL() (RSocket)" )));
+
+    User::LeaveIfError( CheckInitAndHandle( aSocket ) );
+    TInt mediaIndex = GetMediaIndexL( aSocket );
+    User::LeaveIfError( iUtility->DoAddSkippedError( mediaIndex,
+                                                     aError,
+                                                     aDirection ));
+
+    FTRACE(FPrint( _L("CDunTransporter::AddSkippedErrorL() (RSocket) complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Sets service advertisement monitor callback by owner UID
+// Callbacks will be called when advertisement status changes.
+// The callbacks are updated with every successfully completed
+// channel allocation/free (and allocation failure) so it is recommended
+// to call this method after AllocateChannelL().
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::SetAdvertisementMonitorL(
+    TUid aOwnerUid,
+    MDunServAdvMon* aCallback )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::SetAdvertisementMonitorL()" )));
+    TInt i;
+    TInt count;
+    if ( !aCallback )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::SetAdvertisementMonitorL() (aCallback) not initialized!" )));
+        User::Leave( KErrGeneral );
+        }
+    count = iServAdvData.Count();
+    for ( i=0; i<count; i++ )
+        {
+        TDunServAdvData& servAdvData = iServAdvData[i];
+        if ( servAdvData.iOwnerUid==aOwnerUid &&
+             servAdvData.iServAdvMon==aCallback )
+            {
+            FTRACE(FPrint( _L("CDunTransporter::SetAdvertisementMonitorL() (already exist) complete" )));
+            User::Leave( KErrAlreadyExists );
+            }
+        }
+    TDunServAdvData servAdvData;
+    servAdvData.iOwnerUid = aOwnerUid;
+    servAdvData.iServAdvMon = aCallback;
+    iServAdvData.AppendL( servAdvData );
+    FTRACE(FPrint( _L("CDunTransporter::SetAdvertisementMonitorL() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Frees service advertisement monitor callback by plugin UID
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::FreeAdvertisementMonitor(
+    TUid aOwnerUid,
+    MDunServAdvMon* aCallback )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::FreeAdvertisementMonitor()" )));
+    TInt i;
+    TInt count = iServAdvData.Count();
+    for ( i=0; i<count; i++ )
+        {
+        TDunServAdvData& servAdvData = iServAdvData[i];
+        if ( servAdvData.iOwnerUid==aOwnerUid &&
+             servAdvData.iServAdvMon==aCallback )
+            {
+            iServAdvData.Remove( i );
+            FTRACE(FPrint( _L("CDunTransporter::FreeAdvertisementMonitor() complete" )));
+            return KErrNone;
+            }
+        }
+    FTRACE(FPrint( _L("CDunTransporter::FreeAdvertisementMonitor() (not found) complete" )));
+    return KErrNotFound;
+    }
+
+// ---------------------------------------------------------------------------
+// CDunTransporter::CDunTransporter
+// ---------------------------------------------------------------------------
+//
+CDunTransporter::CDunTransporter( MDunPluginManager* aPluginManager,
+                                  TInt aNumOfMaxChannels ) :
+    iUtility( NULL ),
+    iPluginManager( aPluginManager ),
+    iActiveChannels( 0 ),
+    iNumOfMaxChannels( aNumOfMaxChannels ),
+    iInitialized( EFalse ),
+    iAdvertise( ETrue ),
+    iNetwork( NULL )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// CDunTransporter::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CDunTransporter::ConstructL()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::ConstructL()" )));
+    if ( !iPluginManager || iNumOfMaxChannels<0 )
+        {
+        User::Leave( KErrGeneral );
+        }
+    FTRACE(FPrint( _L("CDunTransporter::ConstructL() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Initializes the transporter, must be called as the first operation
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CDunTransporter::InitializeL()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::InitializeL()" )));
+
+    if ( iInitialized )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::InitializeL() (already exists) complete" )));
+        return KErrAlreadyExists;
+        }
+    CDunTransUtils* utility = CDunTransUtils::NewL( *this, iPluginManager );
+    iUtility = static_cast<MDunTransporterUtility*>( utility );
+    MDunTransporterUtilityAux* utilityAux = static_cast<MDunTransporterUtilityAux*>( utility );
+    iChanMan = CDunChanMan::NewL( *this, iUtility, utilityAux, iPluginManager );
+    iNetwork = CDunNetDataport::NewL( iNumOfMaxChannels );
+    iNetwork->InitializeL();
+    iNoteHandler = CDunNoteHandler::NewL();
+    iInitialized = ETrue;
+
+    FTRACE(FPrint( _L("CDunTransporter::InitializeL() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// UnInitializes the transporter, can be called as the last operation
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CDunTransporter::UnInitialize()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::UnInitialize()" )));
+    // first stop channel waiters before deletion
+    if ( iChanMan )
+        {
+        iChanMan->ResetData();
+        }
+    // now ready to remove channel data as no existing waiters
+    TInt i;
+    TInt count = iChannelData.Count();
+    for ( i=0; i<count; i++ )
+        {
+        if ( iChannelData[i].iChannelInUse )
+            {
+            iUtility->DoFreeChannel( i );
+            }
+        }
+    iChannelData.Close();
+    iServAdvData.Close();
+    DeleteTransporter();
+    iInitialized = EFalse;
+    FTRACE(FPrint( _L("CDunTransporter::UnInitialize() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Initialize the transporter
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransporter::InitializeOnDemand()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::InitializeOnDemand()" ) ));
+    if ( !iInitialized )
+        {
+        TRAPD( retTrap, InitializeL() );
+        if ( retTrap != KErrNone )
+            {
+            FTRACE(FPrint( _L("CDunTransporter::InitializeOnDemand() initialize failed!" ) ));
+            return retTrap;
+            }
+        }
+    FTRACE(FPrint( _L("CDunTransporter::InitializeOnDemand() complete" ) ));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// UnInitialize the transporter
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransporter::UnInitializeOnDemand()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::UnInitializeOnDemand()" ) ));
+    if ( !iInitialized )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::UnInitializeOnDemand() (not ready) complete" ) ));
+        return KErrNotReady;
+        }
+    // Check if non-free channel exists, also remove empty channel(s)
+    TInt i;
+    TBool allFree = ETrue;
+    for ( i=iChannelData.Count()-1; i>=0; i-- )
+        {
+        TDunChannelData& channelData = iChannelData[i];
+        if ( !channelData.iChannelInUse )
+            {
+            if ( !channelData.iNetwork )
+                {
+                // iChannelData must not contain data here
+                iChannelData.Remove( i );
+                }
+            }
+        else  // channel not free
+            {
+            allFree = EFalse;
+            FTRACE(FPrint( _L("CDunTransporter::UnInitializeOnDemand() channel found" ) ));
+            }
+        }
+    if ( iChanMan->NumberOfWaiters() > 0 )
+        {
+        allFree = EFalse;
+        FTRACE(FPrint( _L("CDunTransporter::UnInitializeOnDemand() waiter found" ) ));
+        }
+    if ( allFree )
+        {
+        // All channels were free -> uninitialize
+        UnInitialize();
+        FTRACE(FPrint( _L("CDunTransporter::UnInitializeOnDemand() complete" ) ));
+        return KErrNone;
+        }
+    FTRACE(FPrint( _L("CDunTransporter::UnInitializeOnDemand() (not ready) complete" ) ));
+    return KErrNotReady;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns index of media for connection ID
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransporter::GetMediaIndex( TConnId aConnId,
+                                     TDunMediaContext aMediaContext )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::GetMediaIndex()" )));
+    if ( aMediaContext != EDunMediaContextNetwork &&
+         aMediaContext != EDunMediaContextLocal )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::GetMediaIndex() (not supported) complete" )));
+        return KErrNotSupported;
+        }
+    TInt i;
+    TInt count = iChannelData.Count();
+    for ( i=0; i<count; i++ )
+        {
+        TDunChannelData& channelData = iChannelData[i];
+        if ( (aMediaContext==EDunMediaContextNetwork && channelData.iNetwork==aConnId) ||
+             (aMediaContext==EDunMediaContextLocal   && channelData.iComm==aConnId)    ||
+             (aMediaContext==EDunMediaContextLocal   && channelData.iSocket==aConnId) )
+            {
+            if ( !channelData.iChannelInUse )
+                {
+                FTRACE(FPrint( _L("CDunTransporter::GetMediaIndex() (channel free!) complete" ) ));
+                return KErrGeneral;
+                }
+            FTRACE(FPrint( _L("CDunTransporter::GetMediaIndex() complete (i=%d)" ), i));
+            return i;
+            }
+        }
+    FTRACE(FPrint( _L("CDunTransporter::GetMediaIndex() (not found) complete" )));
+    return KErrNotFound;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns index of media for connection ID
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransporter::GetMediaIndexL( TConnId aConnId,
+                                      TDunMediaContext aMediaContext )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::GetMediaIndexL()" )));
+    TInt index = GetMediaIndex( aConnId, aMediaContext );
+    if ( index < 0 )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::GetMediaIndexL() (ERROR) complete" )));
+        User::Leave( index );
+        }
+    FTRACE(FPrint( _L("CDunTransporter::GetMediaIndexL() complete" )));
+    return index;
+    }
+
+// ---------------------------------------------------------------------------
+// Checks initialization and RSubSessionBase() handle
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransporter::CheckInitAndHandle( TConnId aConnId )
+    {
+    FTRACE(FPrint( _L("CDunTransporter::CheckInitAndHandle()" )));
+    if ( !iInitialized )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::CheckInitAndHandle() (not ready) complete" )));
+        return KErrNotReady;
+        }
+    RSubSessionBase* subBase = static_cast<RSubSessionBase*>( aConnId );
+    if ( !subBase->SubSessionHandle() )
+        {
+        FTRACE(FPrint( _L("CDunTransporter::CheckInitAndHandle() (bad handle) complete" )));
+        return KErrBadHandle;
+        }
+    FTRACE(FPrint( _L("CDunTransporter::CheckInitAndHandle() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Deletes own internal data
+// ---------------------------------------------------------------------------
+//
+void CDunTransporter::DeleteTransporter()
+    {
+    FTRACE(FPrint( _L("CDunTransporter::DeleteTransporter()" )));
+    // first, delete channel manager with waiters
+    delete iChanMan;
+    iChanMan = NULL;
+    // second, delete the network object
+    delete iNetwork;
+    iNetwork = NULL;
+    // as last step delete utility class
+    CDunTransUtils* utility = static_cast<CDunTransUtils*>( iUtility );
+    delete utility;
+    iUtility = NULL;
+    // delete note class
+    delete iNoteHandler;
+    iNoteHandler = NULL;
+    FTRACE(FPrint( _L("CDunTransporter::DeleteTransporter() complete" )));
+    }