localconnectivityservice/dun/utils/src/DunNetDataport.cpp
branchRCL_3
changeset 19 0aa8cc770c8a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/localconnectivityservice/dun/utils/src/DunNetDataport.cpp	Tue Aug 31 16:03:15 2010 +0300
@@ -0,0 +1,395 @@
+/*
+* 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:  Dataport specific network resource accessor implementation
+*
+*/
+
+
+#include <mmtsy_names.h>
+#include "DunNetDataport.h"
+#include "DunUtils.h"
+#include "DunDebug.h"
+
+_LIT(DUN_GGP_DATAPORT_CSY_PORT, "::DUN");
+_LIT(DUN_GGP_DATAPORT_CSY, "DATAPORT");
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CDunNetDataport* CDunNetDataport::NewL( TInt aNumOfMaxChannels )
+    {
+    CDunNetDataport* self = new (ELeave) CDunNetDataport( aNumOfMaxChannels );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CDunNetDataport::~CDunNetDataport()
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::~CDunNetDataport()")));
+    TInt i;
+    TInt count = iEntities.Count();
+    for ( i=0; i<count; i++ )
+        {
+        DeleteNetworkEntity( i, ETrue );
+        }
+    DeleteNetwork();
+    FTRACE(FPrint(_L( "CDunNetDataport::~CDunNetDataport() complete")));
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunNetwork (MDunNetDataport -> MDunNetwork).
+// Initializes network for Dataport
+// Must be called before any other operation
+// ---------------------------------------------------------------------------
+//
+void CDunNetDataport::InitializeL()
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::InitializeL()")));
+    AllocatePhoneObjectsL();
+    FTRACE(FPrint(_L( "CDunNetDataport::InitializeL() complete")));
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunNetDataport.
+// Called when channel was created by transporter for Dataport
+// Initializes network for channel creation
+// ---------------------------------------------------------------------------
+//
+TInt CDunNetDataport::AllocateChannel( RComm*& aComm )
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel()")));
+    TInt firstFree = InitializeFirstFreeEntity();
+    if ( firstFree < 0 )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() (not found) complete")));
+        return firstFree;
+        }
+    if ( firstFree >= iEntities.Count() )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() (firstfree failed!) complete")));
+        return KErrGeneral;
+        }
+    TInt retTemp = iEntities[firstFree].iMobileCall.OpenNewCall( iMobileLine );
+    if ( retTemp != KErrNone )
+        {
+        RemoveEntity( firstFree );  // remove unused initialized channel
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() OpenNewCall FAILED %d" ), retTemp));
+        return KErrGeneral;
+        }
+    retTemp = iEntities[firstFree].iMobileCall.Connect();
+    if ( retTemp != KErrNone )
+        {
+        RemoveEntity( firstFree );  // remove unused initialized channel
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() iEntities[%d]->iMobileCall.Connect FAILED %d" ), firstFree, retTemp));
+        return KErrGeneral;
+        }
+    RCall::TCommPort portName;
+    portName.iPort.Copy( DUN_GGP_DATAPORT_CSY );
+    portName.iPort.Append( DUN_GGP_DATAPORT_CSY_PORT );
+    retTemp = iEntities[firstFree].iMobileCall.LoanDataPort( portName );
+    if ( retTemp != KErrNone )
+        {
+        RemoveEntity( firstFree );  // remove unused initialized channel
+        if ( retTemp == KErrEtelPortNotLoanedToClient )
+            {
+            FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() (too big) complete")));
+            return KErrTooBig;
+            }
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() iEntities[%d]->iMobileCall.LoanDataPort FAILED %d" ), firstFree, retTemp));
+        return KErrGeneral;
+        }
+    FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() Created call object at index %d" ), firstFree));
+    retTemp = iEntities[firstFree].iDataport.Open( iCommServer,
+                                                   portName.iPort,
+                                                   ECommExclusive,
+                                                   ECommRoleDTE );
+    if ( retTemp != KErrNone )
+        {
+        RemoveEntity( firstFree );  // remove unused initialized channel
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() FAILED to open dataport %d"), retTemp));
+        return KErrGeneral;
+        }
+    iEntities[firstFree].iDataport.ResetBuffers();
+    iEntities[firstFree].iEntityInUse = ETrue;
+    aComm = &iEntities[firstFree].iDataport;
+    FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() (iEntities[%d]->iDataport) opened"), firstFree));
+    FTRACE(FPrint(_L( "CDunNetDataport::AllocateChannel() complete")));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunNetDataport.
+// Called when channel was deleted/closed by transporter for Dataport
+// Uninitializes network for channel deletion/close
+// ---------------------------------------------------------------------------
+//
+TInt CDunNetDataport::FreeChannel( RComm* aComm )
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::FreeChannel()")));
+    TInt i;
+    TInt count = iEntities.Count();
+    for ( i=0; i<count; i++ )
+        {
+        if ( &iEntities[i].iDataport == aComm )
+            {
+            if ( iEntities[i].iEntityInUse )
+                {
+                break;
+                }
+            }
+        }
+    if ( i >= count )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::FreeChannel() (not found) complete")));
+        return KErrNotFound;
+        }
+    DeleteNetworkEntity( i, ETrue );
+    FTRACE(FPrint(_L( "CDunNetDataport::FreeChannel() (iEntities[%d]->iDataport) freed"), i));
+    FTRACE(FPrint(_L( "CDunNetDataport::FreeChannel() complete")));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MDunNetDataport.
+// Gets index by network ID for Dataport
+// ---------------------------------------------------------------------------
+//
+TInt CDunNetDataport::GetIndexById( RComm* aComm )
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::GetIndexById()")));
+    TInt i;
+    TInt count = iEntities.Count();
+    for ( i=0; i<count; i++ )
+        {
+        TDunDataportEntity& entity = iEntities[i];
+        if ( entity.iEntityInUse )
+            {
+            if ( &entity.iDataport == aComm )
+                {
+                return i;
+                }
+            }
+        }
+    FTRACE(FPrint(_L( "CDunNetDataport::GetIndexById() (not found) complete")));
+    return KErrNotFound;
+    }
+
+// ---------------------------------------------------------------------------
+// CDunNetDataport::CDunNetDataport
+// ---------------------------------------------------------------------------
+//
+CDunNetDataport::CDunNetDataport( TInt aNumOfMaxChannels ) :
+    iNumOfMaxChannels( aNumOfMaxChannels )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// CDunNetDataport::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CDunNetDataport::ConstructL()
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::ConstructL()")));
+    if ( iNumOfMaxChannels < 0 )
+        {
+        User::Leave( KErrGeneral );
+        }
+    TInt retTemp = CDunUtils::ConnectCommsServer( iCommServer );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::ConstructL() FAILED to connect comms server")));
+        User::Leave( retTemp );
+        }
+    retTemp = iCommServer.LoadCommModule( DUN_GGP_DATAPORT_CSY );
+    if ( retTemp != KErrNone )
+        {
+        iCommServer.Close();
+        FTRACE(FPrint(_L( "CDunNetDataport::ConstructL() FAILED to load comm module")));
+        User::Leave( retTemp );
+        }
+    FTRACE(FPrint(_L( "CDunNetDataport::ConstructL() complete")));
+    }
+
+// ---------------------------------------------------------------------------
+// Allocates phone objects for use
+// ---------------------------------------------------------------------------
+//
+void CDunNetDataport::AllocatePhoneObjectsL()
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::AllocatePhoneObjectsL()" ) ));
+    TInt retTemp;
+    retTemp = iTelServer.Connect();
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocatePhoneObjectsL() iTelServer Connect FAILED %d" ), retTemp ));
+        User::Leave( retTemp );
+        }
+    retTemp = iTelServer.LoadPhoneModule( KMmTsyModuleName );
+    if ( retTemp!=KErrNone && retTemp!=KErrAlreadyExists )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocatePhoneObjectsL() LoadPhoneModule FAILED %d" ), retTemp ));
+        User::Leave( retTemp );
+        }
+    retTemp = iMobilePhone.Open( iTelServer, KMmTsyPhoneName );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocatePhoneObjectsL() MobilePhone Open FAILED %d" ), retTemp ));
+        User::Leave( retTemp );
+        }
+    retTemp = iMobileLine.Open( iMobilePhone, KMmTsyDataLineName );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::AllocatePhoneObjectsL() MobileLine Open FAILED %d" ), retTemp ));
+        User::Leave( retTemp );
+        }
+    FTRACE(FPrint(_L( "CDunNetDataport::AllocatePhoneObjectsL() complete" ) ));
+    }
+
+// ---------------------------------------------------------------------------
+// Initializes first free entity
+// ---------------------------------------------------------------------------
+//
+TInt CDunNetDataport::InitializeFirstFreeEntity()
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::InitializeFirstFreeEntity()")));
+    TInt i;
+    TInt retTemp;
+    TInt count = iEntities.Count();
+    for ( i=0; i<count; i++ )
+        {
+        if ( !iEntities[i].iEntityInUse )
+            {
+            FTRACE(FPrint( _L("CDunNetDataport::InitializeFirstFreeEntity() complete" )));
+            return i;
+            }
+        }
+    // Free channel not found, now create new if possible
+    if ( iNumOfMaxChannels!=0 && iEntities.Count()>=iNumOfMaxChannels )
+        {
+        FTRACE(FPrint( _L("CDunNetDataport::InitializeFirstFreeEntity() (too big) complete" )));
+        return KErrTooBig;
+        }
+    TDunDataportEntity emptyEntity;
+    emptyEntity.iEntityInUse = EFalse;
+    retTemp = iEntities.Append( emptyEntity );
+    if ( retTemp != KErrNone )
+        {
+        FTRACE(FPrint( _L("CDunNetDataport::InitializeFirstFreeEntity() (append failed!) complete" )));
+        return retTemp;
+        }
+    FTRACE(FPrint(_L( "CDunNetDataport::InitializeFirstFreeEntity() complete")));
+    return i;
+    }
+
+// ---------------------------------------------------------------------------
+// Remove network entity by index
+// ---------------------------------------------------------------------------
+//
+TInt CDunNetDataport::RemoveEntity( TInt aIndex )
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::RemoveEntity()")));
+    if ( aIndex < 0 ||
+         aIndex >= iEntities.Count() )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::RemoveEntity() (not found) complete")));
+        return KErrNotFound;
+        }
+    DeleteNetworkEntity( aIndex, EFalse );
+    FTRACE(FPrint(_L( "CDunNetDataport::RemoveEntity() complete")));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Deletes own internal data
+// ---------------------------------------------------------------------------
+//
+void CDunNetDataport::DeleteNetwork()
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetwork()")));
+    if ( iMobileLine.SubSessionHandle() )
+        {
+        iMobileLine.Close();
+        FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetwork() mobile line closed")));
+        }
+    if ( iMobilePhone.SubSessionHandle() )
+        {
+        iMobilePhone.Close();
+        FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetwork() mobile phone closed")));
+        }
+    if ( iTelServer.Handle() )
+        {
+        iTelServer.UnloadPhoneModule( KMmTsyModuleName );
+        FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetwork() phone module unloaded")));
+        iTelServer.Close();
+        FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetwork() phone module closed")));
+        }
+    if ( iCommServer.Handle() )
+        {
+        iCommServer.UnloadCommModule( DUN_GGP_DATAPORT_CSY );
+        FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetwork() comm module unloaded")));
+        iCommServer.Close();
+        FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetwork() comm module closed")));
+        }
+    iEntities.Close();
+    FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetwork() complete")));
+    }
+
+// ---------------------------------------------------------------------------
+// Deletes one network entity at index aIndex for Dataport
+// ---------------------------------------------------------------------------
+//
+TInt CDunNetDataport::DeleteNetworkEntity( TInt aIndex, TBool aCheckFree )
+    {
+    FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetworkEntity()")));
+    if ( aIndex < 0 ||
+         aIndex >= iEntities.Count() )
+        {
+        FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetworkEntity() (not found) complete"), aIndex));
+        return KErrGeneral;
+        }
+    TDunDataportEntity& entity = iEntities[aIndex];
+    if ( (aCheckFree&&entity.iEntityInUse) || !aCheckFree )
+        {
+        if ( entity.iDataport.SubSessionHandle() )
+            {
+            // The next will set KSignalDTEOutputs down twice for RComm
+            // local media case because CDunSignalCopy clears them also which
+            // in turn causes plugin to free channel. But this probably won't
+            // cause any harm.
+            entity.iDataport.SetSignals( 0, KSignalDTEOutputs );
+            FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetworkEntity() RComm signals set")));
+            entity.iDataport.Close();
+            FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetworkEntity() RComm closed")));
+            }
+        if ( entity.iMobileCall.SubSessionHandle() )
+            {
+            entity.iMobileCall.RecoverDataPort();
+            FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetworkEntity() Dataport recovered")));
+            entity.iMobileCall.Close();
+            FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetworkEntity() Dataport closed")));
+            }
+        entity.iEntityInUse = EFalse;
+        }
+    FTRACE(FPrint(_L( "CDunNetDataport::DeleteNetworkEntity() complete")));
+    return KErrNone;
+    }