localconnectivityservice/dun/utils/src/DunTransUtils.cpp
branchRCL_3
changeset 19 0aa8cc770c8a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/localconnectivityservice/dun/utils/src/DunTransUtils.cpp	Tue Aug 31 16:03:15 2010 +0300
@@ -0,0 +1,1077 @@
+/*
+* Copyright (c) 2006-2010 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:  Utility class for other CDunTransporter classes
+*
+*/
+
+
+#include <e32base.h>
+#include <e32property.h>
+#include "dundomainpskeys.h"
+#include "DunTransUtils.h"
+#include "DunDataWaiter.h"
+#include "DunUpstream.h"
+#include "DunDownstream.h"
+#include "DunSignalCopy.h"
+#include "DunSignalNotify.h"
+#include "DunNoteHandler.h"
+#include "DunUtils.h"
+#include "DunDebug.h"
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CDunTransUtils* CDunTransUtils::NewL( CDunTransporter& aParent,
+                                      MDunPluginManager* aPluginManager )
+    {
+    CDunTransUtils* self = new (ELeave) CDunTransUtils( aParent,
+                                                        aPluginManager );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CDunTransUtils::~CDunTransUtils()
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::~CDunTransUtils()" )));
+    FTRACE(FPrint( _L("CDunTransUtils::~CDunTransUtils() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// CDunTransUtils::CDunTransUtils
+// ---------------------------------------------------------------------------
+//
+CDunTransUtils::CDunTransUtils( CDunTransporter& aParent,
+                                MDunPluginManager* aPluginManager ) :
+    iParent( aParent ),
+    iChannelData( aParent.iChannelData ),
+    iServAdvData( aParent.iServAdvData ),
+    iPluginManager( aPluginManager )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// CDunTransUtils::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CDunTransUtils::ConstructL()
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::ConstructL()" )));
+    if ( !iPluginManager )
+        {
+        User::Leave( KErrGeneral );
+        }
+    FTRACE(FPrint( _L("CDunTransUtils::ConstructL() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Manages service advertisement status changes
+// ---------------------------------------------------------------------------
+//
+void CDunTransUtils::ManageAdvertisementStatusChange( TBool aAdvertise,
+                                                      TBool aCreation )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::ManageAdvertisementStatusChange()" )));
+    TInt i;
+    TInt count;
+    iParent.iAdvertise = aAdvertise;
+    count = iServAdvData.Count();
+    for ( i=0; i<count; i++ )
+        {
+        TDunServAdvData& servAdvData = iServAdvData[i];
+        if ( servAdvData.iServAdvMon )
+            {
+            if ( aAdvertise )
+                {
+                servAdvData.iServAdvMon->NotifyAdvertisementStart( aCreation );
+                }
+            else
+                {
+                servAdvData.iServAdvMon->NotifyAdvertisementEnd();
+                }
+            }
+        }
+    FTRACE(FPrint( _L("CDunTransUtils::ManageAdvertisementStatusChange() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Creates empty channel data
+// ---------------------------------------------------------------------------
+//
+void CDunTransUtils::CreateEmptyChannelData( TDunChannelData& aChannel )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::CreateEmptyChannelData()" )));
+    aChannel.iNetwork = NULL;
+    aChannel.iComm = NULL;
+    aChannel.iSocket = NULL;
+    aChannel.iChannelName = NULL;
+    aChannel.iUpstreamRW = NULL;
+    aChannel.iDownstreamRW = NULL;
+    aChannel.iBufferUpstream = NULL;
+    aChannel.iBufferDownstream = NULL;
+    aChannel.iBufferUpPtr = NULL;
+    aChannel.iBufferDownPtr = NULL;
+    aChannel.iUpstreamSignalCopy = NULL;
+    aChannel.iDownstreamSignalCopy = NULL;
+    aChannel.iSignalNotify = NULL;
+    aChannel.iOwnerUid = TUid::Null();
+    aChannel.iChannelInUse = EFalse;
+    FTRACE(FPrint( _L("CDunTransUtils::CreateEmptyChannelData() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Creates new buffer if source buffer defined, otherwise already existing
+// buffer will be used
+// ---------------------------------------------------------------------------
+//
+void CDunTransUtils::DoCreateBufferLC( TUint8* aSrcBuffer,
+                                       TPtr8* aSrcPtr,
+                                       TUint8*& aDstBuffer,
+                                       TPtr8*& aDstPtr,
+                                       TInt aBufferLength,
+                                       TInt& aItemsInCs )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateBufferLC()" )));
+    TUint8* buffer;
+    if ( !aSrcBuffer )
+        {
+        buffer = new (ELeave) TUint8[aBufferLength];
+        CleanupStack::PushL( buffer );
+        aItemsInCs++;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateBufferLC() new created" )));
+        }
+    else
+        {
+        buffer = aSrcBuffer;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateBufferLC() existing set" )));
+        }
+    TPtr8* bufferPtr;
+    if ( !aSrcPtr )
+        {
+        bufferPtr = new (ELeave) TPtr8( buffer, aBufferLength, aBufferLength );
+        CleanupStack::PushL( bufferPtr );
+        aItemsInCs++;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateBufferLC() new created" )));
+        }
+    else
+        {
+        bufferPtr = aSrcPtr;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateBufferLC() existing set" )));
+        }
+    aDstBuffer = buffer;
+    aDstPtr = bufferPtr;
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateBufferLC() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Creates new signal copy object if source defined, otherwise already
+// existing will be used
+// ---------------------------------------------------------------------------
+//
+void CDunTransUtils::DoCreateSignalCopyLC( CDunSignalCopy* aSrcSignalCopy,
+                                           CDunSignalCopy*& aDstSignalCopy,
+                                           TInt& aItemsInCs )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateSignalCopyLC()" )));
+    CDunSignalCopy* signalCopy;
+    if ( !aSrcSignalCopy )
+        {
+        signalCopy = CDunSignalCopy::NewL();
+        CleanupStack::PushL( signalCopy );
+        aItemsInCs++;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateSignalCopyLC() new created" )));
+        }
+    else
+        {
+        signalCopy = aSrcSignalCopy;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateSignalCopyLC() existing set" )));
+        }
+    aDstSignalCopy = signalCopy;
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateSignalCopyLC() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Creates new signal notify object if source defined, otherwise already
+// existing will be used
+// ---------------------------------------------------------------------------
+//
+void CDunTransUtils::DoCreateSignalNotifyLC(
+    CDunSignalNotify* aSrcSignalNotify,
+    CDunSignalNotify*& aDstSignalNotify,
+    TInt& aItemsInCs )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateSignalNotifyLC()" )));
+    CDunSignalNotify* signalNotify;
+    if ( !aSrcSignalNotify )
+        {
+        signalNotify = CDunSignalNotify::NewL( this );
+        CleanupStack::PushL( signalNotify );
+        aItemsInCs++;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateSignalNotifyLC() new created" )));
+        }
+    else
+        {
+        signalNotify = aSrcSignalNotify;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateSignalNotifyLC() existing set" )));
+        }
+    aDstSignalNotify = signalNotify;
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateSignalNotifyLC() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Creates transfer objects for reader and writer if sources defined,
+// otherwise already existing ones will be used
+// ---------------------------------------------------------------------------
+//
+void CDunTransUtils::DoCreateUpTransferObjectL( CDunUpstream* aSrcReader,
+                                                CDunUpstream*& aDstReader,
+                                                TInt& aItemsInCs )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateUpTransferObjectL()" )));
+    CDunUpstream* dunReader;
+    if ( !aSrcReader )
+        {
+        dunReader = CDunUpstream::NewL( this );
+        CleanupStack::PushL( dunReader );
+        aItemsInCs++;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateUpTransferObjectL() new created" )));
+        }
+    else
+        {
+        dunReader = aSrcReader;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateUpTransferObjectL() existing set" )));
+        }
+    aDstReader = dunReader;
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateUpTransferObjectL() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Creates transfer objects for reader and writer if sources defined,
+// otherwise already existing ones will be used
+// ---------------------------------------------------------------------------
+//
+void CDunTransUtils::DoCreateDownTransferObjectL( CDunDownstream* aSrcReader,
+                                                  CDunDownstream*& aDstReader,
+                                                  TInt& aItemsInCs )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateDownTransferObjectL()" )));
+    CDunDownstream* dunReader;
+    if ( !aSrcReader )
+        {
+        dunReader = CDunDownstream::NewL( this );
+        CleanupStack::PushL( dunReader );
+        aItemsInCs++;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateDownTransferObjectL() new created" )));
+        }
+    else
+        {
+        dunReader = aSrcReader;
+        FTRACE(FPrint( _L("CDunTransUtils::DoCreateDownTransferObjectL() existing set" )));
+        }
+    aDstReader = dunReader;
+    FTRACE(FPrint( _L("CDunTransUtils::DoCreateDownTransferObjectL() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// Resets/frees network data of aIndex:th channel
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::DeleteOneNetworkData( TInt aIndex )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DeleteOneNetworkData()" )));
+
+    if ( aIndex < 0 ||
+         aIndex >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DeleteOneNetworkData (not found) complete" )));
+        return KErrNotFound;
+        }
+
+    TDunChannelData& channelData = iChannelData[aIndex];
+    if ( !channelData.iChannelInUse )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DeleteOneNetworkData() (channel not found) complete" ), aIndex));
+        return KErrGeneral;
+        }
+
+    // channelData.iDownstreamSignalCopy may or may not exist (optional)
+    // channelData.iSignalNotify may or may not exist (optional)
+    delete channelData.iDownstreamSignalCopy;
+    channelData.iDownstreamSignalCopy = NULL;
+    delete channelData.iSignalNotify;
+    channelData.iSignalNotify = NULL;
+    delete channelData.iDownstreamRW;
+    channelData.iDownstreamRW = NULL;
+
+    FTRACE(FPrint( _L("CDunTransUtils::DeleteOneNetworkData complete()" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Resets/frees network data of aIndex:th channel
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::DeleteOneLocalData( TInt aIndex )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DeleteOneLocalData()" )));
+
+    if ( aIndex < 0 ||
+         aIndex >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DeleteOneLocalData() (not found) complete" )));
+        return KErrNotFound;
+        }
+
+    TDunChannelData& channelData = iChannelData[aIndex];
+    if ( !channelData.iChannelInUse )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DeleteOneLocalData() (channel not found) complete" ), aIndex));
+        return KErrGeneral;
+        }
+
+    // channelData.iUpstreamSignalCopy may or may not exist (optional)
+    delete channelData.iUpstreamSignalCopy;
+    channelData.iUpstreamSignalCopy = NULL;
+    delete channelData.iUpstreamRW;
+    channelData.iUpstreamRW = NULL;
+
+    FTRACE(FPrint( _L("CDunTransUtils::DeleteOneLocalData() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Deletes buffering objects of aIndex:th channel
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::DeleteBuffering( TInt aIndex )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DeleteBuffering()" )));
+
+    if ( aIndex < 0 ||
+         aIndex >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DeleteBuffering() (not found) complete" )));
+        return KErrNotFound;
+        }
+    TDunChannelData& channelData = iChannelData[aIndex];
+    if ( !channelData.iChannelInUse )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DeleteBuffering() (channel not found) complete" ), aIndex));
+        return KErrGeneral;
+        }
+
+    delete channelData.iChannelName;
+    channelData.iChannelName = NULL;
+    delete channelData.iBufferUpstream;
+    channelData.iBufferUpstream = NULL;
+    delete channelData.iBufferDownstream;
+    channelData.iBufferDownstream = NULL;
+    delete channelData.iBufferUpPtr;
+    channelData.iBufferUpPtr = NULL;
+    delete channelData.iBufferDownPtr;
+    channelData.iBufferDownPtr = NULL;
+
+    FTRACE(FPrint( _L("CDunTransUtils::DeleteBuffering() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Initializes first free channel
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::InitializeFirstFreeChannel( TConnId aLocalIdNew )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::InitializeFirstFreeChannel()" )));
+    TInt i;
+    TInt count;
+    TInt retTemp;
+    TInt firstFree = KErrNotFound;
+    count = iChannelData.Count();
+    for ( i=0; i<count; i++ )
+        {
+        TDunChannelData& channelData = iChannelData[i];
+        if ( channelData.iComm==aLocalIdNew ||
+             channelData.iSocket==aLocalIdNew )
+            {
+            FTRACE(FPrint( _L("CDunTransUtils::InitializeFirstFreeChannel() (already exists) complete" )));
+            return KErrAlreadyExists;
+            }
+        if ( !channelData.iChannelInUse && firstFree==KErrNotFound )
+            {
+            firstFree = i;
+            // no "break" here since KErrAlreadyExists needs to be checked
+            }
+        }
+    if ( firstFree >= 0 )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::InitializeFirstFreeChannel() complete" )));
+        return i;
+        }
+    // Free channel not found, now create new if possible
+    TDunChannelData emptyChannel;
+    CreateEmptyChannelData( emptyChannel );
+    retTemp = iChannelData.Append( emptyChannel );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::InitializeFirstFreeChannel() (append failed!) complete" )));
+        return retTemp;
+        }
+    FTRACE(FPrint( _L("CDunTransUtils::InitializeFirstFreeChannel() complete" )));
+    return i;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunTransporterUtility.
+// Allocates a channel by creating and setting local media independent
+// objects
+// This is a common method used by exported local media dependent methods
+// ---------------------------------------------------------------------------
+//
+void CDunTransUtils::DoAllocateChannelL( RComm* aComm,
+                                         TInt& aBufferLength,
+                                         TInt aFirstFree,
+                                         MDunBufferCorrection* aCorrection )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL()" )));
+    TInt retTemp;
+    TInt itemsInCs = 0;
+
+    if ( !iParent.iNetwork )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL() (iNetwork) not initialized!" )));
+        User::Leave( KErrGeneral );
+        }
+
+    FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL() aFirstFree = %d" ), aFirstFree));
+
+    // Allocate network channel
+    RComm* networkEntity;
+    retTemp = iParent.iNetwork->AllocateChannel( networkEntity );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL() network allocation failed" )));
+        if ( retTemp == KErrTooBig )
+            {
+            // Start to show note
+            if ( iParent.iNoteHandler )
+                {
+                iParent.iNoteHandler->IssueRequest();
+                }
+            // Set flag to indicate that advertisement is not possible anymore
+            ManageAdvertisementStatusChange( EFalse );
+            FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL() (too big) complete" )));
+            User::Leave( KErrTooBig );
+            }
+        FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL() (ERROR) complete" )));
+        User::Leave( KErrGeneral );
+        }
+
+    TInt currentLength = networkEntity->ReceiveBufferLength();
+    TInt newLength = currentLength;
+    FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL() buffer length before = %d" ), currentLength));
+    if ( aCorrection )
+        {
+        // Get network side buffer length and request change if required.
+        // Check "newlength>currentLength" here as it is not possible to
+        // increase Dataport's buffer length
+        newLength = aCorrection->NotifyBufferCorrection( currentLength );
+        if ( newLength<=0 || newLength>currentLength )
+            {
+            FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL() unknown buffer length" )));
+            User::Leave( KErrGeneral );
+            }
+        // It is not possible to set Dataport side receive buffer length to any
+        // arbitrary value (currently only 8kB..20kB are supported but that
+        // can't be queried via an API). So here only default buffer size will
+        // be used from Dataport while this component's local buffering uses
+        // Dataport's default buffer size if not adjusted via plugin side.
+        // NOTE: If Dataport side starts to support arbitrary receive buffer
+        // size, it should be changed here if newLength != currentLength.
+        }
+    aBufferLength = newLength;
+    FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL() buffer length after = %d" ), newLength));
+
+    // Get channel data
+
+    TDunChannelData& channelData = iChannelData[aFirstFree];
+
+    // Create buffers and set length
+
+    TUint8* bufferUpstream;
+    TPtr8* bufferUpPtr;
+    DoCreateBufferLC( channelData.iBufferUpstream,
+                      channelData.iBufferUpPtr,
+                      bufferUpstream,
+                      bufferUpPtr,
+                      newLength,
+                      itemsInCs );
+
+    TUint8* bufferDownstream;
+    TPtr8* bufferDownPtr;
+    DoCreateBufferLC( channelData.iBufferDownstream,
+                      channelData.iBufferDownPtr,
+                      bufferDownstream,
+                      bufferDownPtr,
+                      newLength,
+                      itemsInCs );
+
+    // Create signal copy objects
+
+    CDunSignalCopy* upstreamCopy = channelData.iUpstreamSignalCopy;
+    CDunSignalCopy* downstreamCopy = channelData.iDownstreamSignalCopy;
+    if ( aComm )
+        {
+        DoCreateSignalCopyLC( channelData.iUpstreamSignalCopy,
+                              upstreamCopy,
+                              itemsInCs );
+        DoCreateSignalCopyLC( channelData.iDownstreamSignalCopy,
+                              downstreamCopy,
+                              itemsInCs );
+        retTemp = upstreamCopy->SetMedia( aComm,
+                                          networkEntity,
+                                          EDunStreamTypeUpstream );
+        if ( retTemp != KErrNone )
+            {
+            delete upstreamCopy;
+            upstreamCopy = NULL;
+            }
+        retTemp = downstreamCopy->SetMedia( aComm,
+                                            networkEntity,
+                                            EDunStreamTypeDownstream );
+        if ( retTemp != KErrNone )
+            {
+            delete downstreamCopy;
+            downstreamCopy = NULL;
+            }
+        }
+
+    // Create signal notify objects
+
+    CDunSignalNotify* signalNotify = channelData.iSignalNotify;
+    if ( !aComm )  // RSocket
+        {
+        DoCreateSignalNotifyLC( channelData.iSignalNotify,
+                                signalNotify,
+                                itemsInCs );
+        retTemp = signalNotify->SetMedia( networkEntity );
+        if ( retTemp != KErrNone )
+            {
+            delete signalNotify;
+            signalNotify = NULL;
+            }
+        }
+
+    // Create upstream objects
+
+    CDunUpstream* upstreamRW;
+    DoCreateUpTransferObjectL( channelData.iUpstreamRW,
+                               upstreamRW,
+                               itemsInCs );
+    upstreamRW->SetBuffering( bufferUpPtr );
+    upstreamRW->SetMedia( networkEntity, EDunMediaContextNetwork );
+    upstreamRW->SetActivityCallback( this );
+
+    // Create downstream objects
+
+    CDunDownstream* downstreamRW;
+    DoCreateDownTransferObjectL( channelData.iDownstreamRW,
+                                 downstreamRW,
+                                 itemsInCs );
+    downstreamRW->SetBuffering( bufferDownPtr );
+    downstreamRW->SetMedia( networkEntity, EDunMediaContextNetwork );
+
+    // Save values
+
+    channelData.iNetwork = networkEntity;
+    channelData.iUpstreamRW = upstreamRW;
+    channelData.iDownstreamRW = downstreamRW;
+    channelData.iBufferUpstream = bufferUpstream;
+    channelData.iBufferDownstream = bufferDownstream;
+    channelData.iBufferUpPtr = bufferUpPtr;
+    channelData.iBufferDownPtr = bufferDownPtr;
+    channelData.iUpstreamSignalCopy = upstreamCopy;
+    channelData.iDownstreamSignalCopy = downstreamCopy;
+    channelData.iSignalNotify = signalNotify;
+
+    CleanupStack::Pop( itemsInCs );
+
+    // Set flag to indicate that advertisement is now possible
+    ManageAdvertisementStatusChange( ETrue, ETrue );
+
+    FTRACE(FPrint( _L("CDunTransUtils::DoAllocateChannelL() complete" )));
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunTransporterUtility.
+// Adds connection monitor callback for either local media or network side
+// by connection ID
+// Connection monitor will be added to aIndex:th endpoint
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::DoAddConnMonCallback( TInt aIndex,
+                                           MDunConnMon* aCallback,
+                                           TDunDirection aDirection,
+                                           TBool aSignal )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoAddConnMonCallback()" )));
+
+    if ( !iParent.iNetwork )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAddConnMonCallback() (iNetwork) not initialized!" )));
+        return KErrGeneral;
+        }
+
+    if ( aIndex < 0 ||
+         aIndex >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAddConnMonCallback() (not found) complete" )));
+        return KErrNotFound;
+        }
+
+    TDunChannelData& channelData = iChannelData[aIndex];
+
+    // Get upstream and downstream
+    CDunUpstream* upstream = channelData.iUpstreamRW;
+    CDunDownstream* downstream = channelData.iDownstreamRW;
+
+    if ( aDirection == EDunReaderUpstream )
+        {
+        // Initialize stream for AT parsing (ignore errors)
+        upstream->InitializeForAtParsing( downstream,
+                                          channelData.iChannelName,
+                                          upstream,
+                                          downstream );
+        downstream->InitializeForDataPushing( upstream );
+        }
+
+    // Get stream type and operation type
+
+    TDunStreamType streamType =
+        static_cast<TDunStreamType>( aDirection & KDunStreamTypeMask );
+    TDunOperationType operationType =
+        static_cast<TDunOperationType>( aDirection & KDunOperationTypeMask );
+
+    if ( streamType == EDunStreamTypeUpstream )
+        {
+        // If signal copy object(s) exist then add RunL error monitoring for them
+        if ( channelData.iUpstreamSignalCopy )  // optional
+            {
+            // Add callback (ignore errors)
+            channelData.iUpstreamSignalCopy->AddCallback( aCallback );
+            }
+        }
+    else if ( streamType == EDunStreamTypeDownstream )
+        {
+        // If signal copy object(s) exist then add RunL error monitoring for them
+        if ( channelData.iDownstreamSignalCopy )  // optional
+            {
+            // Add callback (ignore errors)
+            channelData.iDownstreamSignalCopy->AddCallback( aCallback );
+            }
+        }
+    else
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAddConnMonCallback() (stream) not initialized!" ) ));
+        return KErrGeneral;
+        }
+
+    // Set signal notify callback
+
+    if ( aSignal && aDirection==EDunReaderDownstream )
+        {
+        if ( !channelData.iSignalNotify )
+            {
+            FTRACE(FPrint( _L("CDunTransUtils::DoAddConnMonCallback() (iSignalNotify) not initialized" )));
+            return KErrGeneral;
+            }
+        // Add callback (ignore errors)
+        channelData.iSignalNotify->AddCallback( aCallback );
+        }
+
+    // Add callback (ignore errors)
+    if ( streamType == EDunStreamTypeUpstream )
+        {
+        upstream->AddConnMonCallback( aCallback, operationType );
+        }
+    else  // streamType == EDunStreamTypeDownstream
+        {
+        downstream->AddConnMonCallback( aCallback, operationType );
+        }
+
+    FTRACE(FPrint( _L("CDunTransUtils::DoAddConnMonCallback() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunTransporterUtility.
+// Adds error to consider as no error condition when doing any of the four
+// endpoint's read/writer operation
+// Error will be added to aIndex:th endpoint
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::DoAddSkippedError( TInt aIndex,
+                                        TInt aError,
+                                        TDunDirection aDirection )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::AddOneSkippedError" ) ));
+    if ( aIndex < 0 ||
+         aIndex >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAddSkippedError() (not found) complete" )));
+        return KErrNotFound;
+        }
+    TDunChannelData& channelData = iChannelData[aIndex];
+    if ( !channelData.iChannelInUse )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAddSkippedError() (channel not found) complete" ), aIndex));
+        return KErrGeneral;
+        }
+
+    if ( aDirection != EDunReaderUpstream  &&
+         aDirection != EDunWriterUpstream &&
+         aDirection != EDunReaderDownstream &&
+         aDirection != EDunWriterDownstream )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAddSkippedError() (ERROR) added" ) ));
+        return KErrNotSupported;
+        }
+
+    TDunStreamType streamType =
+        static_cast<TDunStreamType>( aDirection & KDunStreamTypeMask );
+    TDunOperationType operationType =
+        static_cast<TDunOperationType>( aDirection & KDunOperationTypeMask );
+
+    if ( streamType != EDunStreamTypeUpstream &&
+         streamType != EDunStreamTypeDownstream )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAddSkippedError() (stream) not initialized!" ) ));
+        return KErrGeneral;
+        }
+
+    // Add skipped error (ignore errors)
+
+    if ( streamType == EDunStreamTypeUpstream )
+        {
+        channelData.iUpstreamRW->AddSkippedError( aError, operationType );
+        }
+    else if ( streamType == EDunStreamTypeDownstream )
+        {
+        channelData.iDownstreamRW->AddSkippedError( aError, operationType );
+        }
+    else
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoAddSkippedError() (stream) not initialized!" ) ));
+        return KErrGeneral;
+        }
+
+    FTRACE(FPrint( _L("CDunTransUtils::DoAddSkippedError() complete" ) ));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunTransporterUtility.
+// Issues transfers requests for aIndex:th transfer objects
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::DoIssueTransferRequests( TInt aIndex )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoIssueTransferRequests()" )));
+    if ( aIndex < 0 ||
+         aIndex >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoIssueTransferRequests() (not found) complete" )));
+        return KErrNotFound;
+        }
+    TDunChannelData& channelData = iChannelData[aIndex];
+    if ( !channelData.iChannelInUse )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoIssueTransferRequests() (channel not found) complete" ), aIndex));
+        return KErrGeneral;
+        }
+
+    if ( !channelData.iUpstreamRW )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoIssueTransferRequests() (iUpstreamRW) not initialized!" )));
+        return KErrGeneral;
+        }
+    if ( !channelData.iDownstreamRW )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoIssueTransferRequests() (iDownstreamRW) not initialized!" )));
+        return KErrGeneral;
+        }
+
+    // Below issuing requests on signal objects (CDunSignalCopy,
+    // CDunSignalNotify) before issuing request on read/write objects
+    // (CDunUpstream/CDunDownstream). This is to guarantee that if signals are
+    // already set in local media side then they will be copied to network side
+    // before data.
+
+    if ( channelData.iUpstreamSignalCopy )  // optional (RComm)
+        {
+        channelData.iUpstreamSignalCopy->IssueRequest();
+        }
+    if ( channelData.iDownstreamSignalCopy )  // optional (RComm)
+        {
+        channelData.iDownstreamSignalCopy->IssueRequest();
+        }
+    if ( channelData.iSignalNotify )  // optional (RSocket)
+        {
+        channelData.iSignalNotify->IssueRequest();
+        }
+    channelData.iUpstreamRW->StartStream();
+    channelData.iDownstreamRW->StartStream();
+
+    FTRACE(FPrint( _L("CDunTransUtils::DoIssueTransferRequests() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunTransporterUtility.
+// Stops transfers for aIndex:th transfer objects
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::DoStopTransfers( TInt aIndex )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoStopTransfers()" )));
+    if ( aIndex < 0 ||
+         aIndex >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoStopTransfers() (not found) complete" )));
+        return KErrNotFound;
+        }
+
+    TDunChannelData& channelData = iChannelData[aIndex];
+    if ( !channelData.iChannelInUse )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoStopTransfers() (channel not found) complete" ), aIndex));
+        return KErrGeneral;
+        }
+
+    if ( !channelData.iUpstreamRW )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoStopTransfers() (iUpstreamRW) not initialized!" )));
+        return KErrGeneral;
+        }
+    if ( !channelData.iDownstreamRW )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoStopTransfers() (iDownstreamRW) not initialized!" )));
+        return KErrGeneral;
+        }
+
+    // Now stop operation of signal objects (CDunSignalCopy, CDunSignalNotify)
+    // before stopping operation on read/write objects (CDunUpstream/
+    // CDunDownstream). This is to ensure that signals don't change after
+    // stopping read/write which in turn could cause problems.
+
+    if ( channelData.iUpstreamSignalCopy )  // optional (RComm)
+        {
+        channelData.iUpstreamSignalCopy->Stop();
+        }
+    if ( channelData.iDownstreamSignalCopy )  // optional (RComm)
+        {
+        channelData.iDownstreamSignalCopy->Stop();
+        }
+    if ( channelData.iSignalNotify )  // optional (RSocket)
+        {
+        channelData.iSignalNotify->Stop();
+        }
+    channelData.iUpstreamRW->Stop();
+    channelData.iDownstreamRW->Stop();
+
+    FTRACE(FPrint( _L("CDunTransUtils::DoStopTransfers() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunTransporterUtility.
+// Free aIndex:th channel's objects
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::DoFreeChannel( TInt aIndex )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoFreeChannel()" )));
+
+    TDunChannelData& channelData = iChannelData[aIndex];
+    if ( aIndex < 0 ||
+         aIndex >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoFreeChannel (not found) complete" )));
+        return KErrNotFound;
+        }
+    if ( !channelData.iChannelInUse )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoFreeChannel (already free) complete" )));
+        return KErrNone;
+        }
+    if ( !iParent.iNetwork )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::DoFreeChannel (iNetwork) not initialized!" )));
+        return KErrGeneral;
+        }
+
+    DoStopTransfers( aIndex );
+    DeleteOneNetworkData( aIndex );
+    DeleteOneLocalData( aIndex );
+    DeleteBuffering( aIndex );
+
+    iParent.iNetwork->FreeChannel( channelData.iNetwork );
+
+    channelData.iNetwork = NULL;
+    channelData.iComm = NULL;
+    channelData.iSocket = NULL;
+    channelData.iChannelInUse = EFalse;
+
+    // If note exist then stop it now as no reason to show it anymore
+    if ( iParent.iNoteHandler )
+        {
+        iParent.iNoteHandler->Stop();
+        }
+    // Set flag to indicate that advertisement is now possible
+    ManageAdvertisementStatusChange( ETrue, EFalse );
+
+    FTRACE(FPrint( _L("CDunTransUtils::DoFreeChannel() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunTransporterUtilityAux.
+// Gets local ID counterpart of a network ID
+// ---------------------------------------------------------------------------
+//
+TConnId CDunTransUtils::GetLocalId( RComm* aComm )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::GetLocalId()" )));
+    TInt mediaIndex = iParent.GetMediaIndex( aComm, EDunMediaContextNetwork );
+    if ( mediaIndex < 0 )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::GetLocalId() (ERROR) complete (%d)" ), mediaIndex));
+        return NULL;
+        }
+    if ( mediaIndex >= iChannelData.Count() )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::GetLocalId() (not found) complete" ) ));
+        return NULL;
+        }
+    TDunChannelData& channelData = iChannelData[mediaIndex];
+    if ( channelData.iComm )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::GetLocalId() (iComm) complete" )));
+        return channelData.iComm;
+        }
+    if ( channelData.iSocket )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::GetLocalId() (iSocket) complete" )));
+        return channelData.iSocket;
+        }
+    FTRACE(FPrint( _L("CDunTransUtils::GetLocalId() (ERROR) complete" )));
+    return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// From MDunTransporterUtilityAux.
+// Notifies when serious read/write error is detected on a connection
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::DoNotifyConnectionNotOk(
+    RComm* aComm,
+    RSocket* aSocket,
+    TDunConnectionReason& aConnReason,
+    RPointerArray<MDunConnMon>& aCallbacks )
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::DoNotifyConnectionNotOk()" )));
+    TConnId localId = NULL;
+    if ( aComm )
+        {
+        localId = aComm;
+        }
+    else if ( aSocket )
+        {
+        localId = aSocket;
+        }
+    TInt i;
+    TInt count = aCallbacks.Count();
+    for ( i=0; i<count; i++ )
+        {
+        if ( !aCallbacks[i] )
+            {
+            FTRACE(FPrint( _L("CDunTransUtils::DoNotifyConnectionNotOk() (iCallbacks[%d]) not initialized!" ), i));
+            return KErrGeneral;
+            }
+        TRAP_IGNORE(
+            aCallbacks[i]->NotifyProgressChangeL( localId, aConnReason ) );
+        }
+    FTRACE(FPrint( _L("CDunTransUtils::DoNotifyConnectionNotOk() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunActivityManager.
+// Notifies about activity on a channel
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::NotifyChannelActivity()
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::NotifyChannelActivity()" )));
+    iParent.iActiveChannels++;
+    if ( iParent.iActiveChannels == 1 )
+        {
+        // Now set key and notify (only once) that DUN is active
+        TInt retTemp = RProperty::Set( KPSUidDialupConnStatus,
+                                       KDialupConnStatus,
+                                       EDialupActive );
+        if ( retTemp != KErrNone )
+            {
+            FTRACE(FPrint( _L("CDunTransUtils::NotifyChannelActivity() (ERROR) complete" )));
+            return retTemp;
+            }
+        }
+    FTRACE(FPrint( _L("CDunTransUtils::NotifyChannelActivity() complete" )));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunActivityManager.
+// Notifies about inactivity on a channel
+// ---------------------------------------------------------------------------
+//
+TInt CDunTransUtils::NotifyChannelInactivity()
+    {
+    FTRACE(FPrint( _L("CDunTransUtils::NotifyChannelInactivity()" )));
+    if ( iParent.iActiveChannels <= 0 )
+        {
+        FTRACE(FPrint( _L("CDunTransUtils::NotifyChannelInactivity() (wrong iActiveChannels!) complete" )));
+        return KErrGeneral;
+        }
+    iParent.iActiveChannels--;
+    if ( iParent.iActiveChannels == 0 )
+        {
+        // Now set key and notify (only once) that DUN is inactive
+        TInt retTemp = RProperty::Set( KPSUidDialupConnStatus,
+                                       KDialupConnStatus,
+                                       EDialupInactive );
+        if ( retTemp != KErrNone )
+            {
+            FTRACE(FPrint( _L("CDunTransUtils::NotifyChannelInactivity() (ERROR) complete" )));
+            return retTemp;
+            }
+        }
+    FTRACE(FPrint( _L("CDunTransUtils::NotifyChannelInactivity() complete" )));
+    return KErrNone;
+    }