diff -r 000000000000 -r dd21522fd290 codhandler/codeng/src/Connection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/codhandler/codeng/src/Connection.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,317 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Implementation of class CConnection. +* +* +*/ + + +// INCLUDE FILES + +#include "Connection.h" +#include "CodPanic.h" +#include "CodUtil.h" +#include "CodError.h" +#include "CodLogger.h" +#include +#include +#include + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CConnection::NewL() +// --------------------------------------------------------- +// +CConnection* CConnection::NewL() + { + CConnection* conn = new (ELeave) CConnection(); + CleanupStack::PushL( conn ); + conn->ConstructL(); + CleanupStack::Pop( conn ); + return conn; + } + +// --------------------------------------------------------- +// CConnection::~CConnection() +// --------------------------------------------------------- +// +CConnection::~CConnection() + { + Cancel(); + DoClose(); + } + +// --------------------------------------------------------- +// CConnection::ConnectL() +// --------------------------------------------------------- +// +void CConnection::ConnectL( TUint32 aIap, TRequestStatus* aStatus ) + { + CLOG(( EConn, 2, _L("-> CConnection::ConnectL iap(%d)"), aIap )); + // Misuse asserts. + __ASSERT_ALWAYS( aStatus, CodPanic( ECodInvalidArguments ) ); + // Internal asserts. + __ASSERT_DEBUG( !iParentStatus, CodPanic( ECodInternal ) ); + + iStatus = KErrCodCannotConnect; + if ( iState == EConnected ) + { + // Already connected; do nothing. + CLOG(( EConn, 4, _L(" already connected") )); + iStatus = KErrNone; + } + else if ( iState == EInit ) + { + // Not connected. Create connection. + CLOG(( EConn, 4, _L(" starting connection") )); + // Make this part atomic by pushing closes on the stack. + User::LeaveIfError( iSockServ.Connect() ); + CleanupClosePushL( iSockServ ); + User::LeaveIfError( iConn.Open( iSockServ ) ); + CleanupClosePushL( iConn ); + iConnPref.SetDirection( ECommDbConnectionDirectionOutgoing ); + if ( aIap ) + { + // Use specified IAP. + iConnPref.SetIapId( aIap ); + iConnPref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt ); + } + else + { + // aIap == 0 -> user select. + iConnPref.SetDialogPreference( ECommDbDialogPrefPrompt ); + } + iConn.Start( iConnPref, iStatus ); + iState = EConnecting; + SetActive(); + CleanupStack::Pop( 2 ); // closing iConn and iSockServ + // End of atomic part. + } + else + { + // Not expecting this to be called in other states. + CLOG(( EConn, 0, _L("CConnection::ConnectL: unexpected state (%d)"), \ + iState )); + __ASSERT_ALWAYS( EFalse, CodPanic( ECodInternal ) ); + } + + iParentStatus = aStatus; + *iParentStatus = KRequestPending; + + if ( !IsActive() ) + { + // Unless we have an outstanding connect request (iConn.Start), + // we are done. + Done(); + } + + CLOG(( EConn, 2, _L("<- CConnection::ConnectL") )); + } + +// --------------------------------------------------------- +// CConnection::AttachL() +// --------------------------------------------------------- +// +void CConnection::AttachL( TUint32 aIap ) + { + CLOG(( EConn, 2, _L("-> CConnection::AttachL iap(%d)"), aIap )); + + iStatus = KErrCodCannotConnect; + if ( iState == EConnected ) + { + // Already connected; do nothing. + CLOG(( EConn, 4, _L(" already connected") )); + iStatus = KErrNone; + } + else if ( iState == EInit ) + { + // Not connected. Create connection, or attach to existing. + CLOG(( EConn, 4, _L(" not connected") )); + if ( aIap ) + { + // Make this part atomic by pushing closes on the stack. + User::LeaveIfError( iSockServ.Connect() ); + CleanupClosePushL( iSockServ ); + User::LeaveIfError( iConn.Open( iSockServ ) ); + CleanupClosePushL( iConn ); + TConnectionInfoBuf connInfo; + TUint count; + User::LeaveIfError( iConn.EnumerateConnections( count ) ); + CLOG(( EConn, 4, _L(" %d existing connections"), count )); + TUint i; + for ( i = count; i; i-- ) + { + // Note: GetConnectionInfo expects 1-based index. + User::LeaveIfError( iConn.GetConnectionInfo( i, connInfo ) ); + CLOG(( EConn, 4, _L(" conn(%d) iap(%d)"), \ + i, connInfo().iIapId )); + if ( connInfo().iIapId == aIap ) + { + CLOG(( EConn, 4, _L(" attach"), i, count )); + User::LeaveIfError( iConn.Attach + ( connInfo, RConnection::EAttachTypeNormal ) ); + iState = EConnected; + iStatus = KErrNone; + break; + } + } + CleanupStack::Pop( 2 ); // closing iConn and iSockServ + // End of atomic part. + } + if ( iState == EInit ) + { + CLOG(( EConn, 4, _L(" ended unconnected") )); + iConn.Close(); + iSockServ.Close(); + } + } + else + { + // Not expecting this to be called in other states. + CLOG(( EConn, 0, _L("CConnection::AttachL: unexpected state (%d)"), \ + iState )); + __ASSERT_ALWAYS( EFalse, CodPanic( ECodInternal ) ); + } + User::LeaveIfError( iStatus.Int() ); + + CLOG(( EConn, 2, _L("<- CConnection::AttachL") )); + } + +// --------------------------------------------------------- +// CConnection::Close() +// --------------------------------------------------------- +// +void CConnection::Close() + { + CLOG(( EConn, 2, _L("-> CConnection::Close") )); + Cancel(); + DoClose(); + CLOG(( EConn, 2, _L("<- CConnection::Close") )); + } + +// --------------------------------------------------------- +// CConnection::IsConnected() +// --------------------------------------------------------- +// +TBool CConnection::IsConnected( TUint32& aIap ) + { + TBool connected( EFalse ); + if( iState == EConnected ) + { + TBuf iapId; + _LIT( KFormatIapId, "%S\\%S" ); + TPtrC iap( IAP ); + TPtrC id( COMMDB_ID ); + iapId.Format( KFormatIapId, &iap, &id ); + TInt err = iConn.GetIntSetting( iapId, aIap ); + connected = err ? EFalse : ETrue; + } + return connected; + } + +// --------------------------------------------------------- +// CConnection::CConnection() +// --------------------------------------------------------- +// +CConnection::CConnection() +: CActive( CActive::EPriorityStandard ), + iState( EInit ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------- +// CConnection::ConstructL() +// --------------------------------------------------------- +// +void CConnection::ConstructL() + { + if ( !CodUtil::ApCountL() ) + { + // It's futile to try making a connection without an AP, so leave if + // we don't have any. + User::Leave( KErrCodNoAccessPoint ); + } + } + +// --------------------------------------------------------- +// CConnection::DoCancel() +// --------------------------------------------------------- +// +void CConnection::DoCancel() + { + CLOG(( EConn, 2, _L("-> CConnection::DoCancel") )); + __ASSERT_DEBUG( iState == EConnecting, CodPanic( ECodInternal ) ); + // RConnection has no cancel method matching the async RConnection::Start. + // The only way to cancel is to close the RConnection. + // (Our request will complete with KErrCancel, as expected.) + DoClose(); + Done(); + CLOG(( EConn, 2, _L("<- CConnection::DoCancel") )); + } + +// --------------------------------------------------------- +// CConnection::RunL() +// --------------------------------------------------------- +// +void CConnection::RunL() + { + CLOG(( EConn, 2, _L("-> CConnection::RunL iStatus(%d)"), \ + iStatus.Int() )); + __ASSERT_DEBUG( iState == EConnecting, CodPanic( ECodInternal ) ); + User::LeaveIfError( iStatus.Int() ); // Handle errors in RunError(). + iState = EConnected; + Done(); + CLOG(( EConn, 2, _L("<- CConnection::RunL") )); + } + +// --------------------------------------------------------- +// CConnection::RunError() +// --------------------------------------------------------- +// +TInt CConnection::RunError( TInt LOG_ONLY( aError ) ) + { + CLOG(( EConn, 2, _L("-> CConnection::RunError aError(%d)"), aError )); + __ASSERT_DEBUG( iState == EConnecting, CodPanic( ECodInternal ) ); + DoClose(); + Done(); + CLOG(( EConn, 2, _L("<- CConnection::RunError") )); + return KErrNone; + } + +// --------------------------------------------------------- +// CConnection::DoClose() +// --------------------------------------------------------- +// +void CConnection::DoClose() + { + CLOG(( EConn, 2, _L("CConnection::DoClose") )); + iConn.Close(); + iSockServ.Close(); + iState = EInit; + } + +// --------------------------------------------------------- +// CConnection::Done() +// --------------------------------------------------------- +// +void CConnection::Done() + { + CLOG(( EConn, 2, _L("CConnection::Done iStatus(%d)"), iStatus.Int() )); + __ASSERT_DEBUG( iParentStatus, CodPanic( ECodInternal ) ); + User::RequestComplete( iParentStatus, iStatus.Int() ); + iParentStatus = NULL; + }