/*
* Copyright (c) 2003-2006 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:  Implementation of CCoUtlActive.
*
*/



// INCLUDE FILES
#include    "CCoUtlActive.h"
#include    <mmtsy_names.h>
#include    <nifvar.h>
#include    <pcktcs.h>
#include    <AknGlobalConfirmationQuery.h>
#include    <AknUtils.h>
#include    <StringLoader.h>
#include    <connectutilrsc.rsg>
#include    <avkon.hrh>
#include    <e32property.h>
#include    <PSVariables.h>



// CONSTANTS

// Panic category.
_LIT( KCoUtlPanicCategory, "CoUtl" );

// Enumerates panic reasons
enum 
    {
    // Terminate is already called and operation has not been completed yet. 
    // Cancel before calling Terminate.
    ECoUtlPanicTerminateAlreadyActive = 0
    };

// MACROS

#if defined _DEBUG && !defined __WINS__
// Target UDEB environment - debug traces enabled

#define COUTL_RDEBUG(X)             RDebug::Print(X);
#define COUTL_RDEBUG_INT(X,Y)       RDebug::Print(X,Y);

#else           
// Other environments - debug traces disabled

#define COUTL_RDEBUG(X)
#define COUTL_RDEBUG_INT(X,Y)

#endif


// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CCoUtlActive::CCoUtlActive
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CCoUtlActive::CCoUtlActive()
    : CActive( CActive::EPriorityStandard )
    {
    CActiveScheduler::Add( this );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::~CCoUtlActive
// Destructor.
// -----------------------------------------------------------------------------
//
/***************************************************** 
*   Series 60 Customer / ETel 
*   Series 60  ETel API 
*****************************************************/
CCoUtlActive::~CCoUtlActive()
    {
    Cancel();

    if ( iServer.Handle() )
        {
        // Error is ignored - loading might have failed.
        iServer.UnloadPhoneModule( KMmTsyModuleName ); 
        }

    delete iConfirmationQuery;
    delete iConfirmationText;

    iConnections.Close();
    iPacketService.Close();
    iMobilePhone.Close();
    iServer.Close();
    iConnectionMonitor.CancelNotifications();
    iConnectionMonitor.Close();
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::CurrentState
// -----------------------------------------------------------------------------
//
CCoUtlActive::TState CCoUtlActive::CurrentState() const
    {
    return iState;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::Start
// -----------------------------------------------------------------------------
//
void CCoUtlActive::Start( TRequestStatus& aStatus )
    {
    if ( !IsActive() )
        {
        aStatus = KRequestPending;
        iRequestStatus = &aStatus;
        GoToStateAndComplete( EStarted );
        }
    else
        {
        User::Panic( KCoUtlPanicCategory, ECoUtlPanicTerminateAlreadyActive );
        }
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::RunL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::RunL()
    {
    COUTL_RDEBUG_INT( _L("CCoUtlActive::RunL - State %d: "), iState )
    COUTL_RDEBUG_INT( _L("CCoUtlActive::RunL - Status %d: "), iStatus.Int() )

    // Clean up parameters that might require uninitialisation.
    delete iConfirmationQuery;
    iConfirmationQuery = NULL;

    delete iConfirmationText;
    iConfirmationText = NULL;

    // Leave in case of error.
    User::LeaveIfError( iStatus.Int() );

    // Handle state transitions.
    switch ( iState )
        {
        case EStarted:
            iConnections.Reset();
            GetAttachStatusL();
            break;

        case ECheckIfAttached:
            if ( IsAttached() )
                {
                GetConnectionCountL();
                }
            break;
        
        case EGetConnectionCount:
            iConnectionsIndex = 0;
            CheckConnectionsL();
            break;

        case EGoThroughConnections:
            if ( iConnectionsIndex < iConnections.Count() )
                {
                GoThroughConnectionsGetBearerL();
                }
            else
                {
                GetNetworkModeL();
                }
            break;
        
        case EGoThroughConnectionsGetBearer:
            if ( AcceptConnectionBearer() )
                {
                GoThroughConnectionsGetStatusL();
                }
            else
                {
                // Not accepted - delete and continue to the next.
                iConnections.Remove( iConnectionsIndex );
                GoToStateAndComplete( EGoThroughConnections );
                }
            break;

        case EGoThroughConnectionsGetStatus:
            if ( !IsConnectionActive() )
                {
                // Not accepted - delete and continue to the next.
                iConnections.Remove( iConnectionsIndex );
                }
            else
                {
                // Accepted, go to next one.
                iConnectionsIndex++;
                }

            GoToStateAndComplete( EGoThroughConnections );
            break;

        case ECheckIfNetworkModeIII:
            if ( IsNetworkModeIII() )
                {
                StopConnectionsAndDetachL();
                }
            else
                {
                GoToStateAndComplete( ECheckConnectionCount );
                }
            break;

        case EStopConnectionsAndDetach:
            DetachL();
            break;

        case ECheckConnectionCount:
            if ( !IsConnections() )
                {
                GetAttachModeAndDetachIfRequiredL();
                }
            else 
                {
                ConfirmAllConnectionsTerminationL();
                }
            break;

        case EStopConnectionsAndCheckDetachRequired:
            GetAttachModeAndDetachIfRequiredL();
            break;

        case ECheckDetachRequired:
            if ( IsAttachModeOnDemand() )
                {
                DetachL();
                }
            break;

        case EGetBearerThenNameThenConfirmTermination:
            GetNameThenConfirmTerminationL();
            break;

        case EGetNameThenConfirmTermination:
            ConfirmTerminationL( iConnectionName );
            break;

        case EConfirmAllConnectionsTermination:
            if ( IsConfirmed() )
                {
                StopAllConnectionsAndDetachIfRequiredL();
                }
            break;

        case EDetach:
        case EIdle:
        default:
            break;
        }

    if ( !IsActive() )
        {
        // Operation has been finished.
        iState = EIdle;
        CompleteRequest( KErrNone );
        }

    COUTL_RDEBUG_INT( _L("CCoUtlActive::RunL finished - %d: "), iState )
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::DoCancel
// -----------------------------------------------------------------------------
//
/***************************************************** 
*   Series 60 Customer / ETel 
*   Series 60  ETel API 
*****************************************************/
void CCoUtlActive::DoCancel()
    {
    COUTL_RDEBUG_INT( _L("CCoUtlActive::DoCancel - %d: "), iState )
    // Operation is canceled - cancel ongoing operation and 
    // complete original request with the KErrCancel error code.

    TInt packetServiceCancel = 0;
    TInt connectionMonitorCancel = 0;

    switch ( iState )
        {
        case ECheckIfNetworkModeIII:
            packetServiceCancel = EPacketGetMSClass;
            break;

        case EGetConnectionCount:
            connectionMonitorCancel = EConnMonGetConnectionCount;
            break;

        case EGoThroughConnectionsGetStatus:
        case EGoThroughConnectionsGetBearer:
        case EGetBearerThenNameThenConfirmTermination:
            connectionMonitorCancel = EConnMonGetIntAttribute;
            break;       

        case ECheckDetachRequired:
            packetServiceCancel = EPacketGetAttachMode;
            break;
        
        case EGetNameThenConfirmTermination:
            connectionMonitorCancel = EConnMonGetStringAttribute;
            break;

        case EConfirmAllConnectionsTermination:
            if ( iConfirmationQuery )
                {
                iConfirmationQuery->CancelConfirmationQuery();
                delete iConfirmationQuery;
                iConfirmationQuery = NULL;

                delete iConfirmationText;
                iConfirmationText = NULL;
                }
            break;

        case EDetach:
            packetServiceCancel = EPacketDetach;
            break;

        case EIdle:
        case EStarted:
        case ECheckIfAttached:     
        case EStopConnectionsAndDetach:
        case EGoThroughConnections:
        case ECheckConnectionCount:
        case EStopConnectionsAndCheckDetachRequired:
        default:
            break;
        }

    if ( packetServiceCancel && iPacketService.SubSessionHandle() )
        {
        iPacketService.CancelAsyncRequest( packetServiceCancel );
        }
    if ( connectionMonitorCancel && iConnectionMonitor.Handle() )
        {
        iConnectionMonitor.CancelAsyncRequest( connectionMonitorCancel );
        }

    CompleteRequest( KErrCancel );
    GoToState( EIdle );
    
    COUTL_RDEBUG( _L("CCoUtlActive::DoCancel finished") )
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::RunError
// -----------------------------------------------------------------------------
//
TInt CCoUtlActive::RunError( TInt aError )
    {
    COUTL_RDEBUG_INT( _L("CCoUtlActive::RunError - %d: "), aError )

    // Handles exceptions. Either operation has completed with aError code,
    // or then exception has occured while performing RunL when state has
    // been specified.
    // However, RunL has been implemented in such a way that once asynchronous
    // request has been made, then exception is not raised in that RunL.

    switch ( iState )
        {
        case EStopConnectionsAndDetach:
            // Try to move on.
            GoToStateAndComplete( EDetach );
            break;
            
        case EGoThroughConnectionsGetBearer:
        case EGoThroughConnectionsGetStatus:
            if ( aError == KErrNotFound && 
                ( iConnectionsIndex < iConnections.Count() ) )
                {
                iConnections.Remove( iConnectionsIndex );
                GoToStateAndComplete( EGoThroughConnections );
                break;
                }
            //lint -fallthrough
        case EStarted: 
        case ECheckIfAttached:
        case ECheckIfNetworkModeIII:
        case EGetConnectionCount:
        case EGoThroughConnections:
        case ECheckConnectionCount:
        case EGetBearerThenNameThenConfirmTermination:
        case EGetNameThenConfirmTermination:
        case EConfirmAllConnectionsTermination:
        case EStopConnectionsAndCheckDetachRequired:
        case EDetach:
        case ECheckDetachRequired:
        case EIdle:
        default:
            CompleteRequest( aError );
            GoToState( EIdle );
            break;
        }

    return KErrNone;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GetAttachStatusL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::GetAttachStatusL()
    {
    TInt status = KErrNone;
    TInt statusWcdma = KErrNone;

    //Fetch attach status from RProperty.
    TInt error = RProperty::Get( KUidSystemCategory, KPSUidGprsStatusValue, status );
    if ( error != KErrNone )
        {
        // On error, assume attached - connection monitor will inform
        // detailed information.
        status = EPSGprsAttach;
        }
    error = RProperty::Get( KUidSystemCategory, KPSUidWcdmaStatusValue, statusWcdma );
    if ( error != KErrNone )
        {
        // On error, assume attached - connection monitor will inform
        // detailed information.
        statusWcdma = EPSWcdmaAttach;
        }
    iServiceStatus = status;
    iWcdmaConnectionStatus = statusWcdma;
    GoToStateAndComplete( ECheckIfAttached );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GetNetworkModeL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::GetNetworkModeL()
    {
    PacketServiceL().GetMSClass( iStatus, iCurrentClass, iMaxClass );
    SetActive();
    GoToState( ECheckIfNetworkModeIII );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::StopConnectionsAndDetachL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::StopConnectionsAndDetachL()
    {
    TInt err = DoStopAllConnectionsL();
    GoToStateAndComplete( 
        EStopConnectionsAndDetach,
        err );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GetConnectionCountL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::GetConnectionCountL()
    {
    GoToState( EGetConnectionCount );
    ConnectionMonitorL().GetConnectionCount( iConnectionCount, iStatus );
    SetActive();
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::CheckConnectionsL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::CheckConnectionsL()
    {
    RConnectionMonitor& monitor = ConnectionMonitorL();
    iConnections.Reset();

    // Go through all connections
    // Note indexing from 1, 2, 3, .., iConnectionCount.
    for ( TUint index = 1; index <= iConnectionCount; index++ )
        {
        TConnectionId id;
        TUint subConnectionCount = 0;
        
        TInt err = 
            monitor.GetConnectionInfo( 
                index, 
                id.iConnectionId, 
                subConnectionCount );

        // SubConnectionIds are not used.
        id.iSubConnectionId = 0;

        if ( err != KErrNotFound )
            {
            // the KErrNotFound error code indicates that connection has
            // already been dropped, so those indices are simply ignored.
            User::LeaveIfError( err );
            User::LeaveIfError( iConnections.Append( id ) );
            }
        }

    GoToStateAndComplete( EGoThroughConnections );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GoThroughConnectionsGetBearerL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::GoThroughConnectionsGetBearerL()
    {
    TConnectionId& current = iConnections[ iConnectionsIndex ];
    ConnectionMonitorL().GetIntAttribute( 
        current.iConnectionId,
        current.iSubConnectionId,
        KBearer,
        iConnectionBearer,
        iStatus );
    SetActive();
    GoToState( EGoThroughConnectionsGetBearer );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GoThroughConnectionsGetStatusL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::GoThroughConnectionsGetStatusL()
    {
    TConnectionId& current = iConnections[ iConnectionsIndex ];
    ConnectionMonitorL().GetIntAttribute( 
        current.iConnectionId,
        current.iSubConnectionId,
        KConnectionStatus,
        iConnectionStatus,
        iStatus );
    SetActive();
    GoToState( EGoThroughConnectionsGetStatus );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GetAttachModeAndDetachIfRequiredL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::GetAttachModeAndDetachIfRequiredL()
    {
    PacketServiceL().GetAttachMode( iStatus, iAttachMode );
    SetActive();
    GoToState( ECheckDetachRequired );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::ConfirmAllConnectionsTerminationL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::ConfirmAllConnectionsTerminationL()
    {
    if ( iConnections.Count() == 1 ) // Exactly one connection
        {
        GetBearerThenNameThenConfirmTerminationL();
        }
    else
        {
        ConfirmTerminationL( iConnections.Count() );
        }
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::ConfirmTerminationL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::ConfirmTerminationL( TInt aAmount )
    {
    HBufC* text =
        StringLoader::LoadLC( 
            R_COUTL_CONFIRM_CONNECTIONS,
            aAmount );

    TPtr ptr = text->Des();
    
    // Convert digits in the string to correct digit type.
    AknTextUtils::DisplayTextLanguageSpecificNumberConversion( ptr );

    DoConfirmTerminationL( *text );
    CleanupStack::Pop( text );
    iConfirmationText = text;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::ConfirmTerminationL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::ConfirmTerminationL( const TDesC& aName )
    {
    HBufC* text = 
        StringLoader::LoadLC( 
            R_COUTL_CONFIRM_ONE_CONNECTION,
            aName );

    DoConfirmTerminationL( *text );
    CleanupStack::Pop( text );
    iConfirmationText = text;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::DoConfirmTerminationL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::DoConfirmTerminationL( const TDesC& aText )
    {
    CAknGlobalConfirmationQuery* confirmationQuery =
        CAknGlobalConfirmationQuery::NewLC();
    confirmationQuery->ShowConfirmationQueryL(
        iStatus,
        aText );
    CleanupStack::Pop( confirmationQuery );
    
    SetActive();
    iConfirmationQuery = confirmationQuery;
    GoToState( EConfirmAllConnectionsTermination );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GetBearerThenNameThenConfirmTerminationL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::GetBearerThenNameThenConfirmTerminationL()
    {
    TConnectionId& id = iConnections[ 0 ]; // first
    ConnectionMonitorL().GetIntAttribute( 
        id.iConnectionId,
        id.iSubConnectionId,
        KBearer,
        iConnectionBearer,
        iStatus );
    SetActive();
    GoToState( EGetBearerThenNameThenConfirmTermination );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GetNameThenConfirmTerminationL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::GetNameThenConfirmTerminationL()
    {
    TConnectionId& id = iConnections[ 0 ]; // first

    TUint attribute = KIAPName;
    if ( iConnectionBearer == EBearerExternalGPRS || 
         iConnectionBearer == EBearerExternalEdgeGPRS ||
         iConnectionBearer == EBearerExternalWCDMA )
        {
        attribute = KAccessPointName;
        }

    ConnectionMonitorL().GetStringAttribute(
        id.iConnectionId,
        id.iSubConnectionId,
        attribute,
        iConnectionName,
        iStatus );
    SetActive();
    GoToState( EGetNameThenConfirmTermination );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::StopAllConnectionsAndDetachIfRequiredL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::StopAllConnectionsAndDetachIfRequiredL()
    {
    TInt err = DoStopAllConnectionsL();
    GoToStateAndComplete( 
        EStopConnectionsAndCheckDetachRequired,
        err );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::DoStopAllConnectionsL
// -----------------------------------------------------------------------------
//
TInt CCoUtlActive::DoStopAllConnectionsL()
    {
    TInt err = KErrNone;

    for ( TInt index = iConnections.Count() - 1; index >= 0; index-- )
        {
        const TConnectionId& id = iConnections[ index ];

        TInt result = ConnectionMonitorL().SetBoolAttribute(
            id.iConnectionId, id.iSubConnectionId, KConnectionStop, ETrue );
        if ( result == KErrNotFound )
            {
            // the KErrNotFound error code is ignored, because connection
            // may have been ended by another client.
            result = KErrNone;
            }

        // Combine error codes.
        err = Min( err, result );
        }

    return err;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::DetachL
// -----------------------------------------------------------------------------
//
void CCoUtlActive::DetachL()
    {
    PacketServiceL().Detach( iStatus );
    SetActive();
    GoToState( EDetach );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::IsAttached
// -----------------------------------------------------------------------------
//
inline TBool CCoUtlActive::IsAttached() const
    {
    return ( 
        ( iServiceStatus != EPSGprsUnattached ) ||
        ( iWcdmaConnectionStatus != EPSWcdmaUnattached ) );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::IsNetworkModeIII
// -----------------------------------------------------------------------------
//
inline TBool CCoUtlActive::IsNetworkModeIII() const
    {
    return 
        ( iCurrentClass == RPacketService::EMSClassAlternateMode ) || 
        ( iCurrentClass == RPacketService::EMSClassPacketSwitchedOnly ) ||
        ( iCurrentClass == RPacketService::EMSClassCircuitSwitchedOnly );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::IsConnections
// -----------------------------------------------------------------------------
//
inline TBool CCoUtlActive::IsConnections() const
    {
    return iConnections.Count();
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::AcceptConnectionBearer
// -----------------------------------------------------------------------------
//
inline TBool CCoUtlActive::AcceptConnectionBearer() const
    {
    return ( iConnectionBearer == EBearerGPRS ) ||
           ( iConnectionBearer == EBearerEdgeGPRS ) ||
           ( iConnectionBearer == EBearerWCDMA ) ||
           ( iConnectionBearer == EBearerExternalGPRS ) ||
           ( iConnectionBearer == EBearerExternalEdgeGPRS ) ||
           ( iConnectionBearer == EBearerExternalWCDMA );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::IsAttachModeOnDemand
// -----------------------------------------------------------------------------
//
inline TBool CCoUtlActive::IsAttachModeOnDemand() const
    {
    return ( iAttachMode == RPacketService::EAttachWhenNeeded );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::IsConnectionActive
// -----------------------------------------------------------------------------
//
inline TBool CCoUtlActive::IsConnectionActive() const
    {
    return ( iConnectionStatus != KConnectionClosed ) &&
           ( iConnectionStatus != KLinkLayerClosed );
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::Confirmed
// -----------------------------------------------------------------------------
//
inline TBool CCoUtlActive::IsConfirmed() const
    {
    return iStatus.Int() == EAknSoftkeyYes;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::TelServerL
// -----------------------------------------------------------------------------
//
/*****************************************************
*   Series 60 Customer / TSY
*   Needs customer TSY implementation
*****************************************************/
inline RTelServer& CCoUtlActive::TelServerL()
    {
    if ( !iServer.Handle() )
        {
        // ETel server session will be closed if any of the following operations
        // fail. In this way, the above Handle condition is sufficient; if 
        // session has been opened, then it has been initialised properly as
        // well.
        CleanupClosePushL( iServer ); 
        User::LeaveIfError( iServer.Connect() );
        User::LeaveIfError( 
            iServer.SetExtendedErrorGranularity( 
                RTelServer::EErrorExtended ) );
        User::LeaveIfError( iServer.LoadPhoneModule( KMmTsyModuleName ) );
        CleanupStack::Pop(); // Success
        }

    return iServer;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::MobilePhoneL
// -----------------------------------------------------------------------------
//
/***************************************************** 
*   Series 60 Customer / ETel 
*   Series 60  ETel API 
*****************************************************/
inline RMobilePhone& CCoUtlActive::MobilePhoneL()
    {
    if ( !iMobilePhone.SubSessionHandle() )
        {
        User::LeaveIfError( iMobilePhone.Open( TelServerL(), KMmTsyPhoneName ) );
        }

    return iMobilePhone;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::PacketServiceL
// -----------------------------------------------------------------------------
//
/***************************************************** 
*   Series 60 Customer / ETel 
*   Series 60  ETel API 
*****************************************************/
inline RPacketService& CCoUtlActive::PacketServiceL()
    {
    if ( !iPacketService.SubSessionHandle() )
        {
        User::LeaveIfError( iPacketService.Open( MobilePhoneL() ) );
        }

    return iPacketService;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::ConnectionMonitorL
// -----------------------------------------------------------------------------
//
inline RConnectionMonitor& CCoUtlActive::ConnectionMonitorL()
    {
    if ( !iConnectionMonitor.Handle() )
        {
        User::LeaveIfError( iConnectionMonitor.ConnectL() );
        User::LeaveIfError( iConnectionMonitor.NotifyEventL( *this ) ); 
        }

    return iConnectionMonitor;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::CompleteRequest
// -----------------------------------------------------------------------------
//
void CCoUtlActive::CompleteRequest( TInt aErrorCode )
    {
    if ( iRequestStatus )
        {
        User::RequestComplete( iRequestStatus, aErrorCode );
        iRequestStatus = NULL;
        }
    }
    
// -----------------------------------------------------------------------------
// CCoUtlActive::EventL
// -----------------------------------------------------------------------------
//    
void CCoUtlActive::EventL( const CConnMonEventBase &aConnMonEvent )
    {
    COUTL_RDEBUG_INT( _L("CCoUtlActive::EventL - Event %d: "), aConnMonEvent.EventType() )
    switch ( aConnMonEvent.EventType() )
		{
        case EConnMonDeleteConnection:
            {
            if ( IsActive() && iConfirmationQuery )
                {
                COUTL_RDEBUG( _L("CCoUtlActive::EventL - Cancel()") )
                Cancel();
                }
		    }
			break;
		default:
			break;
		} 
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GoToState
// -----------------------------------------------------------------------------
//
inline void CCoUtlActive::GoToState( TState aNewState )
    {
    iState = aNewState;
    }

// -----------------------------------------------------------------------------
// CCoUtlActive::GoToStateAndComplete
// -----------------------------------------------------------------------------
//
inline void CCoUtlActive::GoToStateAndComplete( TState aNewState, TInt aError )
    {
    GoToState( aNewState );
    TRequestStatus* status = &iStatus;
    User::RequestComplete( status, aError );
    SetActive();
    }

//  End of File  
