--- /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 <e32std.h>
+#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