diff -r 000000000000 -r d0791faffa3f mtpfws/mtpfw/src/cmtpconnectionmgr.cpp --- /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; + } +