IMPSengine/engsrv/src/impsactivecirmonitor.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IMPSengine/engsrv/src/impsactivecirmonitor.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,434 @@
+/*
+* 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:  Im circle Manager.
+*
+*
+*/
+
+
+// INCLUDE FILES
+#include    <e32std.h>
+#include    "impsactivecirmonitor.h"
+#include    "impsutils.h"
+#include    <msgconnmanagerapi.h>
+
+
+// CONSTANTS
+
+// TCP/IP CIR ping interval in seconds
+const TInt KImpsPingInt = 900;
+
+// MACROS
+#ifndef _DEBUG
+#define _NO_IMPS_LOGGING_
+#endif
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+
+//**********************************
+// CImpsCirManager
+//**********************************
+CImpsCirManager::CImpsCirManager(
+    MImpsCSPSession& aServer,
+    TInt aPriority )
+        : CActive( aPriority ),
+        iServer( aServer ),
+        iState( EImpsCirOffline ),
+        iCanceled( EFalse ),
+        iManager( NULL ),
+        iTCPWatcher( NULL ),
+        iUDPWatcher( NULL ),
+        iChannels ( 0 ),
+        iReqChannels ( 0 )
+    {
+    // Add this to the scheduler
+    CActiveScheduler::Add( this );
+    }
+
+// EPOC default constructor can leave.
+void CImpsCirManager::ConstructL()
+    {
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: Constructor rel200517.1+" ) );
+#endif
+    }
+
+// Two-phased constructor.
+CImpsCirManager* CImpsCirManager::NewL(
+    MImpsCSPSession& aServer,
+    TInt aPriority )
+    {
+    CImpsCirManager* self = new ( ELeave ) CImpsCirManager(
+        aServer, aPriority );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+
+// Destructor
+CImpsCirManager::~CImpsCirManager()
+    {
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: Destructor" ) );
+#endif
+    Cancel();
+    if ( iTCPWatcher )
+        {
+        delete iTCPWatcher;
+        iTCPWatcher = NULL;
+        }
+    if ( iUDPWatcher )
+        {
+        iUDPWatcher->Destroy();
+        iUDPWatcher = NULL;
+        }
+
+    // REcomSession::FinalClose() is not called here but in the engine core
+    // just before active acheduler is stopped.
+
+    }  //lint !e1740 iManager is not deleted here, it's only reference
+
+// ---------------------------------------------------------
+// CImpsCirManager::OpenChL
+// ---------------------------------------------------------
+//
+void CImpsCirManager::OpenChL(
+    TImpsCirChannels aChannels,
+    MMsgConnManager& aManager,
+    TUint aServerport,
+    const TDesC& aServerAddress,
+    const TDesC8& aCSPSessionID,
+    TUint aUDPPort )
+    {
+    if  ( ( iState == EImpsCirOnline ) || ( aChannels == 0 ) )
+        {
+#ifndef _NO_IMPS_LOGGING_
+        CImpsClientLogger::Log( _L( "CImpsCirManager: OpenChL ignored" ) );
+#endif
+        iServer.CirChOpened();
+        // Nothing to open
+        return;
+        }
+
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: OpenChL" ) );
+#endif
+
+    iManager = &aManager;
+    iReqChannels = aChannels;
+    iUDPPort = aUDPPort;
+
+    // Start TCP watcher first if required
+    if ( ( aChannels & KImpsCirTcp ) && ~( iChannels & KImpsCirTcp ) )
+        {
+        DoOpenTCPL( aServerport, aServerAddress,
+                    aCSPSessionID );
+        // Another watcher started in RunL if needed
+        }
+    // UPD start here if TCP not required
+    else if ( ( aChannels & KImpsCirUdp ) && ~( iChannels & KImpsCirUdp ) )
+        {
+        DoOpenUDP( iUDPPort );
+        }
+    }
+
+// ---------------------------------------------------------
+// CImpsCirManager::DoOpenTCPL
+// ---------------------------------------------------------
+//
+void CImpsCirManager::DoOpenTCPL(
+    TUint aServerport,
+    const TDesC& aServerAddress,
+    const TDesC8& aCSPSessionID )
+    {
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: DoOpenTCPL" ) );
+#endif
+    // If opening fails then this method leaves. TCP is tried to open
+    // so CSP session gets information about failure.
+    // Start watchers, TCP watcher first
+    iTCPWatcher = CImpsTcpCirWatcher::NewL( KImpsPingInt, *this, *iManager );
+    iState = EImpsCirOpeningTcp;
+    ActivateMe();
+    iTCPWatcher->StartTCPWatcherL( iStatus, aServerport, aServerAddress, aCSPSessionID );
+    }
+
+// ---------------------------------------------------------
+// CImpsCirManager::DoOpenUDP
+// ---------------------------------------------------------
+//
+void CImpsCirManager::DoOpenUDP(
+    TUint aUDPPort )
+    {
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: DoOpenUDP" ) );
+#endif
+    // UPD watcher registeration
+    TInt err = KErrNone;
+    TRAP( err, iUDPWatcher = CImpsUdpCirWatcher::NewL() );
+    if ( err )
+        {
+        // UDP open erros are reported to csp session asynchronously via RunL
+        DoHandleError( err, EImpsUdpCir );
+        }
+    TRAP( err, iUDPWatcher->RegisterCirReceiverL( *this, aUDPPort ) );
+    if ( err )
+        {
+        // UDP open erros are reported to csp session asynchronously via RunL
+        DoHandleError( err, EImpsUdpCir );
+        }
+    else
+        {
+        iChannels = iChannels | KImpsCirUdp;
+        }
+    }
+
+// ---------------------------------------------------------
+// CImpsCirManager::CloseCh
+// ---------------------------------------------------------
+//
+void CImpsCirManager::CloseCh(
+    TImpsCirChannels aChannels )
+    {
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: CloseCh" ) );
+#endif
+
+    // If active then have to wait
+    Cancel();
+
+    if ( !( aChannels & iChannels ) ||
+         iState == EImpsCirOffline ||
+         ( !iTCPWatcher && !iUDPWatcher ) )
+        {
+        // Nothing to close
+        return;
+        }
+
+    // Channels that required to be closed
+    iReqChannels = aChannels;
+
+    // Close TCP
+    if ( ( iReqChannels & KImpsCirTcp ) &&
+         ( iChannels & KImpsCirTcp ) )
+        {
+        iTCPWatcher->StopTCPWatcher();
+        iChannels = iChannels & ~KImpsCirTcp;
+        }
+    // Close UDP
+    if ( ( iReqChannels & KImpsCirUdp ) &&
+         ( iChannels & KImpsCirUdp ) )
+        {
+        TInt err = KErrNone;
+        TRAP( err, iUDPWatcher->UnregisterCirReceiverL( *this ) );
+        iChannels = iChannels & ~KImpsCirUdp;
+        }
+
+    // Destructor handles the rest of the shut down activies
+
+    iState = EImpsCirOffline;
+    }
+
+// ---------------------------------------------------------
+// CImpsCirManager::CirReceivedL
+// ---------------------------------------------------------
+//
+void CImpsCirManager::CirReceivedL(
+    const TDesC8& aMessage,
+    const TImpsSupportedCirTypes aCirType )
+    {
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: CirReceivedL type=%d" ), aCirType );
+#endif
+
+    // notice: This is not very clear how to handle multiple IP-CIR channels
+    // Better keep on listening them
+    /*
+    if ( ( aCirType == EImpsTcpCir ) && ( iChannels & KImpsCirUdp ) )
+        {
+        // Stop UDP if another CIR channel in use
+        iUDPWatcher->StopUDPWatcher();
+        }
+    else if ( ( aCirType == EImpsUdpCir ) && ( iChannels & KImpsCirTcp ) )
+        {
+        // Stop TCP if another CIR channel in use
+        iTCPWatcher->StopTCPWatcher();
+        }
+        */
+
+    iServer.CirMessageL( aMessage );
+
+    }
+
+// ---------------------------------------------------------
+// CImpsCirManager::HandleErrorL
+// ---------------------------------------------------------
+//
+void CImpsCirManager::HandleErrorL(
+    const TInt aReceiverError,
+    const TImpsSupportedCirTypes aCirType )
+    {
+    DoHandleError( aReceiverError, aCirType );
+    }
+
+// ---------------------------------------------------------
+// CImpsCirManager::DoHandleError
+// ---------------------------------------------------------
+//
+void CImpsCirManager::DoHandleError(
+    const TInt aReceiverError,
+    const TImpsSupportedCirTypes aCirType )
+    {
+
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: DoHandleError %d type=%d" ),
+                            aReceiverError, aCirType );
+#endif
+
+    // We suppose that this is not called if this is active, but
+    // better to check anyway. Then do the following actions.
+    // - Yield to ifself with an error code.
+    // - In RunL stop channels
+    // - Then call iServer.CirChError() that destroys us.
+
+    if ( !IsActive() )
+        {
+        iStatus = KRequestPending;
+        SetActive();
+        iCanceled = EFalse;
+        TRequestStatus* s = &iStatus;
+        User::RequestComplete( s, aReceiverError );
+        }
+    }
+
+// ---------------------------------------------------------
+// CImpsCirManager::RunL
+// ---------------------------------------------------------
+//
+void CImpsCirManager::RunL( )
+    {
+
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: RunL %d" ), iStatus.Int() );
+#endif
+
+    if ( iCanceled )
+        {
+#ifndef _NO_IMPS_LOGGING_
+        CImpsClientLogger::Log( _L( "CImpsCirManager: RunL ignored" ) );
+#endif
+        iCanceled = EFalse;
+        if ( iChannels )
+            {
+            iState = EImpsCirOnline;
+            }
+        else
+            {
+            iState = EImpsCirOffline;
+            }
+        return;
+        }
+
+    // Error handling, common for both open methods and HandleErrorL methods.
+    // CSP session entity will call destrcutor, so no need to do else than
+    // close watcher
+    if ( iStatus.Int() != KErrNone )
+        {
+        if ( iState == EImpsCirOnline )
+            {
+            if ( iChannels & KImpsCirTcp )
+                {
+                iTCPWatcher->StopTCPWatcher();
+                }
+            if ( iChannels & KImpsCirUdp )
+                {
+                TInt err = KErrNone;
+                TRAP( err, iUDPWatcher->UnregisterCirReceiverL( *this ) );
+                }
+            iState = EImpsCirOffline;
+            }
+        iServer.CirChError();
+        return;
+        }
+
+    // asynchronous TCP CIR opening completed
+    if ( iState == EImpsCirOpeningTcp )
+        {
+        iChannels = iChannels | KImpsCirTcp;
+        // if UDP were supported
+        if ( ( iReqChannels & KImpsCirUdp ) &&
+             !( iChannels & KImpsCirUdp ) )
+            {
+            // load UDP listener synchronously
+            DoOpenUDP( iUDPPort );
+            }
+        }
+
+    // Everything is OK and opened
+    iState = EImpsCirOnline;
+    iServer.CirChOpened();
+    }
+
+// ---------------------------------------------------------
+// CImpsCirManager::DoCancel
+// ---------------------------------------------------------
+//
+void CImpsCirManager::DoCancel()
+    {
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsCirManager: DoCancel" ) );
+#endif
+    // This just waits IAP connection operation to end.
+    iCanceled = ETrue;
+    if ( iState == EImpsCirOpeningTcp )
+        {
+        // This returns KErrCancel if an operation is not ready
+        iTCPWatcher->StopTCPWatcher();
+        }
+    }
+
+// ---------------------------------------------------------
+// CImpsCirManager::ActivateMe
+// ---------------------------------------------------------
+//
+TInt CImpsCirManager::ActivateMe(  )
+    {
+    if ( !IsActive() )
+        {
+        iStatus = KRequestPending;
+        SetActive();
+        iCanceled = EFalse;
+        return KErrNone;
+        }
+    else
+        {
+        return KErrNotReady;
+        }
+    }
+
+
+
+//  End of File
+