--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/localconnectivityservice/dun/utils/src/DunTransUtils.cpp Fri Jun 11 14:27:06 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;
+ }