diff -r 000000000000 -r 094583676ce7 IMPSengine/engsrv/src/impsactiveconnmonitor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IMPSengine/engsrv/src/impsactiveconnmonitor.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,502 @@ +/* +* Copyright (c) 2003-2005 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: Imps connection manager. +* +* +*/ + + + + +// INCLUDE FILES +#include +#include "ImpsSendReceive.h" +#include "impsactiveconnmonitor.h" +#include "impsutils.h" +#include "impserrors.h" + + +// CONSTANTS + +// MACROS +#ifndef _DEBUG +#define _NO_IMPS_LOGGING_ +#endif + +// LOCAL CONSTANTS AND MACROS + +// Wait time 8 seconds before IAP re-opened +const TInt KImpsWaitIAPOpen = 8000000; + + + +// ================= MEMBER FUNCTIONS ======================= + +// C++ default constructor can NOT contain any code, that +// might leave. +// + +//********************************** +// CImpsConnManager +//********************************** +CImpsConnManager::CImpsConnManager( + CImpsSendReceive2& aSender, + TInt aPriority ) + : CActive( aPriority ), + iSender( aSender ), + iState( EImpsNoAP ), + iCmd( EImpsTransNone ), + iConnState( EMsgBearerActive ), + iManager( NULL ), + iRunL( EFalse ) + { + ( void ) iTimer.CreateLocal(); + // Add this to the scheduler + CActiveScheduler::Add( this ); + } + +// EPOC default constructor can leave. +void CImpsConnManager::ConstructL() + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: CONSTRUCTL rel200540.3f cman=%d" ), ( TInt )this ); +#endif + iManager = NewMsgConnManagerL( 0 ); + } + +// Two-phased constructor. +CImpsConnManager* CImpsConnManager::NewL( + CImpsSendReceive2& aSender, TInt aPriority ) + { + CImpsConnManager* self = new ( ELeave ) CImpsConnManager( + aSender, aPriority ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + + +// Destructor +CImpsConnManager::~CImpsConnManager() + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: DESTRUCTOR begins cman=%d" ), ( TInt )this ); +#endif + Cancel(); + iTimer.Close(); + if ( iManager ) + { + iManager->Destroy(); + } + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: DESTRUCTOR ends cman=%d" ), ( TInt )this ); +#endif + } + +// --------------------------------------------------------- +// CImpsConnManager::OpenAPL +// --------------------------------------------------------- +// +void CImpsConnManager::OpenAPL( + TInt aIAP, TBool aDelayed ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: OpenAPL iap=%d delay=%d cman=%d" ), + aIAP, aDelayed, ( TInt )this ); +#endif + if ( IsActive () ) + { + // Notice: We should not be here +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: BUSY cman=%d ****" ), ( TInt )this ); +#endif + User::Leave( KErrNotReady ); + } + + iConnState = EMsgBearerActive; + + if ( ( aDelayed || iRunL ) && iCmd != EImpsTransWaitOpen ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d OpenAPL extra wait ****" ), ( TInt )this ); +#endif + iCmd = EImpsTransWaitOpen; + iState = EImpsNoAP; + iIAP = aIAP; + SetActive(); + // Give time for Connection Manager + iTimer.After( iStatus, KImpsWaitIAPOpen ); + return; + } + iCmd = EImpsTransNone; +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d calls SetAccessPointIDL" ), ( TInt )this ); +#endif + iManager->SetAccessPointIDL( aIAP ); +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d calls RemoveEventSubscriber and AddEventSubscriberL" ), ( TInt )this ); +#endif + // Verify that in error cases nothing is left hanging + iManager->RemoveEventSubscriber( this ); + iManager->AddEventSubscriberL( this ); + iStatus = KRequestPending; +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d calls StartConnection" ), ( TInt )this ); +#endif + iManager->StartConnection( iStatus ); + iCmd = EImpsTransOpenAP; + iState = EImpsNoAP; + iIAP = aIAP; + SetActive(); + } + +// --------------------------------------------------------- +// CImpsConnManager::CloseAP +// --------------------------------------------------------- +// +void CImpsConnManager::CloseAP( TBool /*aTotalClose*/ ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: CloseAP state=%d %d cman=%d" ), + iState, IsActive(), ( TInt )this ); +#endif + + if ( iState == EImpsNoAP && !IsActive() ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d CloseAP already closed" ), ( TInt )this ); +#endif + iCmd = EImpsTransNone; + iConnState = EMsgBearerActive; + // Engine core waits any kind of response in shut down + iSender.APStatusEvent( EImpsNoAP, KErrNone, ETrue ); +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d CloseAP ends" ), ( TInt )this ); +#endif + return; + } + else if ( iState == EImpsNoAP && IsActive() ) + { + // Waiting open timer must be cancelled + if ( iCmd == EImpsTransWaitOpen ) + { + // This cancels the timer +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d err: CANCEL ***" ), ( TInt )this ); +#endif + Cancel(); + iCmd = EImpsTransCloseAP; + iIAP = 0; + // Now do the trick to go to own RunL and call there appropriate callback. + ActivateMe(); + return; + } + else if ( iCmd == EImpsTransOpenAP ) + { + // Open APL is pending and must be cancelled +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d calls CancelStartL ****" ), ( TInt )this ); +#endif + TRAPD( errx, iManager->CancelStartL() ); + if ( errx ) + { + // Normally this is not needed, but Cancel StartL may leave with + // KErrAbort if there is no pending request. + // VERY RARE situation. + iCmd = EImpsTransNone; + iSender.APStatusEvent( EImpsNoAP, KErrNone, ETrue ); + return; + } + // Normal case continues in RunL +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d CloseAP ends" ), ( TInt )this ); +#endif + return; + } + } + else if ( IsActive() ) // + { + // Previous close is not completed. +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d BUSY ***" ), ( TInt )this ); +#endif + return; + } + iCmd = EImpsTransCloseAP; + iIAP = 0; + iStatus = KRequestPending; + SetActive(); + // Notice: Rest of activities in RunL and destructor +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d calls RemoveEventSubscriber" ), ( TInt )this ); +#endif + iManager->RemoveEventSubscriber( this ); +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d calls StopConnection" ), ( TInt )this ); +#endif + iManager->StopConnection( iStatus ); + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d CloseAP ends" ), ( TInt )this ); +#endif + } + + +// --------------------------------------------------------- +// CImpsConnManager::HandleBearerEventL +// --------------------------------------------------------- +// +void CImpsConnManager::HandleBearerEventL( TBool aIsAuthClose, TMsgBearerEvent aBearerEvent ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( + _L( "CImpsConnManager: HandleBearerEventL %d authClose=%d cman=%d" ), aBearerEvent, aIsAuthClose, ( TInt )this ); +#endif + iConnState = aBearerEvent; + if ( IsActive() ) + { + // pending open/close, so wait that instead +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( + _L( "CImpsConnManager: HandleBearerEventL SPECIAL cmd=%d cman=%d ***" ), iCmd, ( TInt )this ); +#endif + + /* Notice: + This is a little bit tricky situation because of Msg ConnManager DLL + cannot quarantee the right order of events for us! Thus it is + possible that we first get bearer-event and after that response + for open/close connection request although the actual order + is that open/close is first completed and then the bearer event has + taken a place. + + /@ + \ \ + ___> \ + (__O) \ + (____@) \ + (____@) \ + (__o)_ \ + \ \ + */ + + switch ( iConnState ) + { + case EMsgBearerActive: + iSender.APStatusEvent( EImpsOnline, KErrNone, EFalse ); + break; + case EMsgBearerSuspended: + iSender.APStatusEvent( EImpsOffline, KErrNone, EFalse ); + break; + case EMsgBearerLost: + default: + { + // RunL handles rest of the activities + // when iConnState == EMsgBearerLost. + break; + } + }; + } + else // regular case + { + switch ( iConnState ) + { + case EMsgBearerActive: + iSender.APStatusEvent( EImpsOnline, KErrNone, EFalse ); + break; + case EMsgBearerSuspended: + iSender.APStatusEvent( EImpsOffline, KErrNone, EFalse ); + break; + case EMsgBearerLost: + default: + { + iState = EImpsNoAP; + iSender.APStatusEvent( EImpsNoAP, KErrNone, EFalse, aIsAuthClose ); + break; + } + } + }; +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d HandleBearerEventL ends" ), ( TInt )this ); +#endif + } + +// --------------------------------------------------------- +// CImpsConnManager::ManagerHandleL +// --------------------------------------------------------- +// +MMsgConnManager& CImpsConnManager::ManagerHandleL() const + { + if ( !iManager ) + { + User::Leave( KErrBadHandle ); + } + return *iManager; + } + +// --------------------------------------------------------- +// CImpsConnManager::Destroy +// --------------------------------------------------------- +// +void CImpsConnManager::Destroy() + { + if ( iManager ) + { + iManager->Destroy(); + } + iManager = NULL; + } + +// --------------------------------------------------------- +// CImpsConnManager::RunL +// --------------------------------------------------------- +// +void CImpsConnManager::RunL( ) + { + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: RunL ret=%d cmd=%d state=%d conn=%d cman=%d" ), + iStatus.Int(), iCmd, iState, iConnState, ( TInt )this ); +#endif + + iRunL = ETrue; + TInt ret = iStatus.Int(); + + // We have delayed and given time for connection manager to work properly + if ( iCmd == EImpsTransWaitOpen ) + { + if ( !ret ) + { + TInt errx = KErrNone; + TRAP( errx, OpenAPL( iIAP, EFalse ) ); + } + else + { + iState = EImpsNoAP; + iCmd = EImpsTransNone; + iSender.APStatusEvent( iState, ret, ETrue ); + } + } + else if ( iCmd == EImpsTransOpenAP ) + { + iCmd = EImpsTransNone; + iState = EImpsNoAP; + if ( ret == KErrNone ) + { + if ( iConnState != EMsgBearerLost ) + { + // AP is opened successfully + iState = EImpsOnline; + } + else // iConnState == EMsgBearerLost + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: err: cman=%d iConnState==EMsgBearerLost ****" ), ( TInt )this ); +#endif + // Special case where order of events from ConnManager is not valid. + ret = KImpsErrorNoIAP; + // KImpsErrorNoIAP error code has a special error handling + // in CSPSession class. + } + } + iSender.APStatusEvent( iState, ret, ETrue ); + } + else if ( iCmd == EImpsTransCloseAP ) + { + iCmd = EImpsTransNone; + iState = EImpsNoAP; + // Notice that iSender must exist, i.e. DeleteCSP() cancels + // everything before deleting CSP session entity referred by iSender. + iSender.APStatusEvent( EImpsNoAP, ret, ETrue ); + } + else if ( iCmd == EImpsTransCloseDelay ) + { + // This is a special case where this object is used for yielding. + // Actually it calls CloseAP + iCmd = EImpsTransNone; + iSender.CloseTr( ); + } + else + { + iCmd = EImpsTransNone; + } + iRunL = EFalse; +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d RunL ends" ), ( TInt )this ); +#endif + } + +// --------------------------------------------------------- +// CImpsConnManager::DoCancel +// --------------------------------------------------------- +// +void CImpsConnManager::DoCancel() + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d DoCancel" ), ( TInt )this ); +#endif + TImpsTransCmd orig = iCmd; + iCmd = EImpsTransNone; + if ( orig == EImpsTransOpenAP ) + { + // cancel +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d calls CancelStartL *****" ), ( TInt )this ); +#endif + TInt errx = KErrNone; + TRAP( errx, iManager->CancelStartL() ); + } + else if ( orig == EImpsTransCloseAP ) + { + iState = EImpsNoAP; + } + // This just waits IAP connection operation to end. + else if ( iCmd == EImpsTransWaitOpen ) + { + iTimer.Cancel(); + } + } + +TInt CImpsConnManager::ActivateMe( ) + { + // This yields the control to the server thread active scheduler + if ( !IsActive() ) + { + iStatus = KRequestPending; + SetActive(); + TRequestStatus* s = &iStatus; + User::RequestComplete( s, KErrNone ); + return KErrNone; + } + else + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d KErrNotReady ****" ), ( TInt )this ); +#endif + return KErrNotReady; + } + } + +TInt CImpsConnManager::StartDelayed( ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "CImpsConnManager: cman=%d StartDelayed" ), ( TInt )this ); +#endif + iCmd = EImpsTransCloseDelay; + return ActivateMe(); + } + + +// End of File