mtpfws/mtpfw/src/cmtpconnectionmgr.cpp
changeset 0 d0791faffa3f
child 1 f8e15b44d440
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpfws/mtpfw/src/cmtpconnectionmgr.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,410 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "cmtpconnectionmgr.h"
+
+#include "cmtpconnection.h"
+#include "cmtptransportplugin.h"
+#include "mmtptransportconnection.h"
+
+// Class constants.
+__FLOG_STMT(_LIT8(KComponent,"ConnectionMgr");)
+
+/**
+CMTPConnectionMgr factory method.
+@leave If a failure occurs, one of the system wide error codes.
+*/
+CMTPConnectionMgr* CMTPConnectionMgr::NewL()
+    {
+    CMTPConnectionMgr* self = new(ELeave) CMTPConnectionMgr();
+    return self;
+    }
+
+/**
+Destructor.
+*/  
+CMTPConnectionMgr::~CMTPConnectionMgr()
+    {
+    StopTransport( iTransportUid, ETrue );
+    iConnections.ResetAndDestroy();
+    iSuspendedTransports.Reset();
+    iSuspendedTransports.Close();
+    delete iTransportTrigger;
+    __FLOG_CLOSE;
+    }
+
+/**
+Provides a reference to the connection with the specified connection identifier.
+@param aConnectionId The connection identifier.
+@return The connection reference.
+@leave KErrNotFound If a connection with the specified identifier does not 
+exist.
+*/
+EXPORT_C CMTPConnection& CMTPConnectionMgr::ConnectionL(TUint aConnectionId) const
+    {   
+    __FLOG(_L8("ConnectionL - Entry"));
+    
+    TInt idx(ConnectionFind(aConnectionId));
+    
+    __FLOG_VA((_L8("idx is %d "), idx));
+    __ASSERT_ALWAYS((idx != KErrNotFound), User::Invariant());
+    
+    __FLOG(_L8("ConnectionL - Exit"));
+    return *iConnections[idx];
+    }
+
+/**
+Provides a count of the number of currently open connections.
+@return The count of currently open connections.
+*/  
+TUint CMTPConnectionMgr::ConnectionCount() const
+    {
+    return iConnections.Count();
+    }
+
+/**
+Provide a non-const reference to the located at the specified position within 
+the connection table.
+@return A non-const reference to the required connection.
+*/
+CMTPConnection& CMTPConnectionMgr::operator[](TInt aIndex) const
+    {
+    return *iConnections[aIndex];
+    }
+    
+/**
+Returns the current transportID.
+@return The CMTPTransportPlugin interface implementation UID.
+*/
+EXPORT_C TUid CMTPConnectionMgr::TransportUid()
+    {
+    return iTransportUid;
+    }
+
+EXPORT_C void CMTPConnectionMgr::StartTransportL(TUid aTransport)
+    {
+    StartTransportL( aTransport, NULL );
+    }
+
+/**
+Loads and starts up the MTP transport plug-in with the specified 
+CMTPTransportPlugin interface implementation UID. Only one MTP transport 
+plug-in can be loaded at any given time.
+@param The CMTPTransportPlugin interface implementation UID.
+@leave KErrNotSupported If an attempt is made to load a second MTP transport
+plug-in.
+@leave One of the system wide error codes, if a processing failure occurs.
+@see StopTransport
+*/
+EXPORT_C void CMTPConnectionMgr::StartTransportL(TUid aTransport, const TAny* aParameter)
+    {
+	__FLOG(_L8("StartTransportL - Entry"));
+	
+    if (iTransport)
+        {
+        if (aTransport != iTransportUid)
+            {
+            // Multiple transports not currently supported.
+            User::Leave(KErrNotSupported);
+            }
+        }
+    else
+        {
+
+        iTransport = CMTPTransportPlugin::NewL(aTransport, aParameter);
+
+        TRAPD(err, iTransport->StartL(*this));
+		if (err != KErrNone)
+			{
+			__FLOG_VA( ( _L8("StartTransportL error, error code = %d"), err) );
+			delete iTransport;
+			iTransport = NULL;
+			User::Leave(err);
+			}
+        iTransportUid = aTransport;       
+		
+        iTransportCount++;
+        UnsuspendTransport( iTransportUid );
+        }
+		
+	__FLOG(_L8("StartTransportL - Exit"));
+    }
+
+/**
+Queue the transport to start when there is no running transport
+@param aTransport, The CMTPTransportPlugin interface implementation UID.
+@param aParameter, reserved
+@leave One of the system wide error codes, if the operation fails.
+*/
+EXPORT_C void CMTPConnectionMgr::QueueTransportL( TUid aTransport, const TAny* /*aParameter*/ )
+    {
+    __FLOG_VA( ( _L8("+QueueTransportL( 0x%08X )"), aTransport.iUid ) );
+    __ASSERT_DEBUG( ( KErrNotFound == iSuspendedTransports.Find( aTransport ) ), User::Invariant() );
+    iSuspendedTransports.InsertL( aTransport, 0 );
+    __FLOG( _L8("-QueueTransportL") );
+    }
+
+EXPORT_C void CMTPConnectionMgr::SetClientSId(TUid aSecureId)
+	{
+	iSecureId=aSecureId;
+	}
+
+/**
+Shuts down and unloads the MTP transport plug-in with the specified 
+CMTPTransportPlugin interface implementation UID.
+@param The CMTPTransportPlugin interface implementation UID.
+*/
+EXPORT_C void CMTPConnectionMgr::StopTransport(TUid aTransport)
+    {
+    StopTransport( aTransport, EFalse );
+    }
+
+/**
+Shuts down and unloads the MTP transport plug-in with the specified 
+CMTPTransportPlugin interface implementation UID.
+@param aTransport The CMTPTransportPlugin interface implementation UID.
+@param aByBearer If ETrue, it means the transport plugin is stopped because the bearer is turned off or not activated.
+*/
+EXPORT_C void CMTPConnectionMgr::StopTransport( TUid aTransport, TBool aByBearer )
+    {
+	__FLOG(_L8("StopTransport - Entry"));
+	
+    if ( ( iTransport ) && ( aTransport == iTransportUid ) )
+        {
+        if ( !aByBearer )
+            {
+            TRAP_IGNORE( SuspendTransportL( aTransport ) );
+            }
+        iTransport->Stop(*this);
+        delete iTransport;
+        iTransport = NULL;
+        iTransportUid = KNullUid;
+        iTransportCount--;
+
+
+        }
+    if ( aByBearer )
+        {
+        UnsuspendTransport( aTransport );
+        }
+		
+	__FLOG(_L8("StopTransport - Exit"));
+    }
+
+/**
+Shuts down and unloads all active MTP transport plug-ins.
+*/
+EXPORT_C void CMTPConnectionMgr::StopTransports()
+    {
+    if (iTransport)
+        {
+        iTransport->Stop(*this);
+        delete iTransport;
+        iTransport = NULL;
+        iTransportUid = KNullUid;
+        iTransportCount--;
+        }
+    }
+
+/**
+Returns the number of active Transports.
+@return Number of active transports
+*/
+EXPORT_C TInt CMTPConnectionMgr::TransportCount() const
+    {
+	return iTransportCount;
+    }
+
+void CMTPConnectionMgr::ConnectionClosed(MMTPTransportConnection& aTransportConnection)
+    {
+    __FLOG(_L8("ConnectionClosed - Entry"));
+    
+    TInt idx(ConnectionFind(aTransportConnection.BoundProtocolLayer().ConnectionId()));
+    __FLOG_VA((_L8("idx is %d "), idx));
+    __ASSERT_DEBUG((idx != KErrNotFound), User::Invariant());
+    
+    CMTPConnection* connection(iConnections[idx]);
+    connection->ConnectionSuspended();
+    
+    ResumeSuspendedTransport();
+    
+    __FLOG(_L8("ConnectionClosed - Exit"));
+    }
+    
+void CMTPConnectionMgr::ConnectionOpenedL(MMTPTransportConnection& aTransportConnection)
+    {   
+    __FLOG(_L8("ConnectionOpenedL - Entry"));
+    
+    TUint impUid = aTransportConnection.GetImplementationUid();
+    TInt idx = ConnectionFind(impUid);
+    CMTPConnection* connection = NULL;
+    
+    if (idx == KErrNotFound)
+        {
+        // take transport connection implementation UID as connection ID
+        connection = CMTPConnection::NewLC(impUid, aTransportConnection);
+        iConnections.InsertInOrder(connection, iConnectionOrder);
+        CleanupStack::Pop(connection); 
+        }
+    else
+        {
+        connection = iConnections[idx];
+        }
+    connection->ConnectionResumedL(aTransportConnection);
+    
+    __FLOG(_L8("ConnectionOpenedL - Exit"));
+    }
+
+TBool CMTPConnectionMgr::DeleteConnection(TUint aConnectionId)
+    {
+    __FLOG(_L8("DeleteConnection - Entry"));
+    
+    TBool ret = EFalse;    
+    TInt idx = ConnectionFind(aConnectionId);
+    
+    if (idx != KErrNotFound)
+        {
+        CMTPConnection* connection(iConnections[idx]);
+        iConnections.Remove(idx);
+        delete connection;
+        ret = ETrue;
+        }
+    
+    __FLOG(_L8("DeleteConnection - Entry"));
+    
+    return ret;
+    }
+
+EXPORT_C TUid CMTPConnectionMgr::ClientSId()
+	{
+	return iSecureId;
+	}
+/**
+Constructor.
+*/
+CMTPConnectionMgr::CMTPConnectionMgr() :
+    iConnectionOrder(ConnectionOrderCompare),
+    iShutdownConnectionIdx(KErrNotFound),
+	iTransportUid(KNullUid)
+    {
+    __FLOG_OPEN(KMTPSubsystem, KComponent);    
+    }
+
+/**
+Provides the connections table index of the connection with the specified 
+connection identifier.
+@param The identifier of the required connection.
+@return The connection table index of the required connection, or KErrNotFound
+if the connection identifier could not be found.
+*/ 
+TInt CMTPConnectionMgr::ConnectionFind(TUint aConnectionId) const
+    {
+    __FLOG_VA((_L8("ConnectionFind - Entry with connectionId %d "), aConnectionId));
+    TInt ret(KErrNotFound);
+    
+    const TUint noConnections = iConnections.Count();
+    for (TUint i(0); ((i < noConnections) && (ret == KErrNotFound)); i++)
+        {
+        TInt id(iConnections[i]->ConnectionId());
+        if (aConnectionId == id)
+            {
+            ret = i;
+            break;
+            }
+        }
+    __FLOG(_L8("ConnectionFind - Exit"));    
+    return ret;
+    }
+
+/**
+Determines the relative order of two CMTPConnection objects based on their 
+connection IDs.
+@return Zero, if the two objects are equal; a negative value, if the aFirst 
+is less than aSecond, or; a positive value, if the aFirst is greater than 
+aSecond.
+*/
+TInt CMTPConnectionMgr::ConnectionOrderCompare(const CMTPConnection& aFirst, const CMTPConnection& aSecond)
+    {
+    return aFirst.ConnectionId() - aSecond.ConnectionId();
+    }
+
+/**
+Append the transport to the suspended transport list
+@param aTransport, The implementation UID of the suspended transport plugin
+@leave One of the system wide error codes, if the operation fails.
+*/
+void CMTPConnectionMgr::SuspendTransportL( TUid aTransport )
+    {
+    __FLOG_1( _L8("+SuspendTransportL( 0x%08X )"), aTransport );
+    if ( KErrNotFound == iSuspendedTransports.Find( aTransport ) )
+        {
+        iSuspendedTransports.AppendL( aTransport );
+        }
+    __FLOG( _L8("-SuspendTransportL") );
+    }
+
+/**
+Remove transport from the suspended transports list
+@param aTransport, The CMTPTransportPlugin interface implementation UID 
+*/
+void CMTPConnectionMgr::UnsuspendTransport( TUid aTransport )
+    {
+    __FLOG_1( _L8("+UnsuspendTransport( 0x%08X )"), aTransport.iUid );
+    TInt idx = iSuspendedTransports.Find( aTransport );
+    if ( KErrNotFound != idx )
+        {
+        __FLOG_1( _L8("Remove the number %d suspended transport"), idx );
+        iSuspendedTransports.Remove( idx );
+        }
+    __FLOG( _L8("-UnsuspendTransport") );
+    }
+
+/**
+Prepare to resume suspended transport
+*/
+void CMTPConnectionMgr::ResumeSuspendedTransport()
+    {
+    __FLOG( _L8("+ResumeSuspendedTransport") );
+    const TInt count = iSuspendedTransports.Count();
+    if ( ( count > 0 )
+        // If the transport was just switched and suspended, it shouldn't be resumed.
+        && ( iTransportUid != iSuspendedTransports[count-1] ) )
+        {
+        __FLOG( _L8("Found suspended transport(s).") );
+        if ( !iTransportTrigger )
+            {
+            iTransportTrigger = new( ELeave ) CAsyncCallBack( CActive::EPriorityStandard );
+            }
+        __ASSERT_DEBUG( ( !iTransportTrigger->IsActive() ), User::Invariant() );
+        TCallBack callback( CMTPConnectionMgr::DoResumeSuspendedTransport, this );
+        iTransportTrigger->Set( callback );
+        iTransportTrigger->CallBack();
+        }
+    __FLOG( _L8("-ResumeSuspendedTransport") );
+    }
+
+/**
+Resume suspended transport
+@param aSelf, The memory address of the CMTPConnectionMgr instance
+@return KErrNone, but the value is ignored.
+*/
+TInt CMTPConnectionMgr::DoResumeSuspendedTransport( TAny* aSelf )
+    {
+    CMTPConnectionMgr* self = reinterpret_cast< CMTPConnectionMgr* >( aSelf );
+    __ASSERT_DEBUG( ( self->iSuspendedTransports.Count() > 0 ), User::Invariant() );
+    TRAP_IGNORE( self->StartTransportL( self->iSuspendedTransports[self->iSuspendedTransports.Count()-1] ) );
+    return KErrNone;
+    }
+