sipplugins/sippsystemstatemonitor/src/sipvpnmonitorao.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 12 Mar 2010 15:44:11 +0200
branchRCL_3
changeset 9 1e1cc61f56c3
child 26 822e1f077722
permissions -rw-r--r--
Revision: 201007 Kit: 201008

/*
* Copyright (c) 2010 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 : P&S key monitor for communication between SIP Profile 
*               server and VPN client
* Name        : sipvpnmonitorao.cpp
* Part of     : Sip System State Monitor
* Version     : 1.0
*
*/

//  INCLUDE FILES
#include "sipvpnmonitorao.h"
#include <vpnsipobserverpskeys.h>
#include <sipsystemstateobserver.h>

_LIT_SECURITY_POLICY_PASS( KSIPVpnAlwaysPass );

static const TInt KMicroSecondsInSecond = 1000000;
static const TInt KGuardTimerSeconds = 10; 

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::NewL
// -----------------------------------------------------------------------------
//
CSipVpnMonitorAo* CSipVpnMonitorAo::NewL()
    {
    CSipVpnMonitorAo* self = new( ELeave )CSipVpnMonitorAo();
    
    CleanupStack::PushL ( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    
    return self;
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::ConstructL
// -----------------------------------------------------------------------------
//
void CSipVpnMonitorAo::ConstructL()
    {
    iGuardTimer = CPeriodic::NewL( EPriorityNormal );
    
    // Define a P&S key for communication between SIP Profile Server and VPN client.
    TInt err = iProperty.Define( KPSVpnSipUid, KVpnSipState, RProperty::EInt, 
                                 KSIPVpnAlwaysPass, KSIPVpnAlwaysPass );
    if ( KErrNone != err && KErrAlreadyExists != err && 
            KErrPermissionDenied != err )
        {
        User::Leave( err );
        }

    User::LeaveIfError( iProperty.Attach( KPSVpnSipUid, KVpnSipState ) );

    iProperty.Subscribe( iStatus );
    SetActive();
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::CSipVpnMonitorAo
// -----------------------------------------------------------------------------
//
CSipVpnMonitorAo::CSipVpnMonitorAo():
    CActive(EPriorityStandard)
    {
    CActiveScheduler::Add( this );
    iCount = 0;
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::~CSipVpnMonitorAo
// -----------------------------------------------------------------------------
//
CSipVpnMonitorAo::~CSipVpnMonitorAo()
    {
    if ( iGuardTimer )
        {
        iGuardTimer->Cancel();
        delete iGuardTimer;
		iGuardTimer = NULL;
        }
        
    CActive::Cancel();
    
    iProperty.Close();
    iProperty.Delete( KPSVpnSipUid, KVpnSipState );
    
    iObservers.Close();
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::AddObserverL
// -----------------------------------------------------------------------------
//
void CSipVpnMonitorAo::AddObserverL( 
    MSipSystemStateObserver& aObserver )
    {
    iObservers.InsertInAddressOrderL( &aObserver );
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::RemoveObserver
// -----------------------------------------------------------------------------
//    
void CSipVpnMonitorAo::RemoveObserver(
    MSipSystemStateObserver& aObserver )
    {
    TInt index = iObservers.Find( &aObserver );
    if ( index >= 0 )
        {
        iObservers.Remove( index ); 
        }
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::NotifyObservers
// -----------------------------------------------------------------------------
//
void CSipVpnMonitorAo::NotifyObservers()
    {
    // Notify observers (SIP Profile Server) about the P&S key change.
    for ( TInt i = iObservers.Count()-1; i >= 0; i-- )
        {
        iObservers[i]->SystemVariableUpdated( 
            CSipSystemStateMonitor::EVpnState, 
            0,
            iState);
        }

    // Start a guard timer so that VPN client don't wait forever for completion
    // of deregistration.
    if ( iObservers.Count() && iState == CSipSystemStateMonitor::EVpnInitiating )
        {
        iGuardTimer->Cancel();
        iGuardTimer->Start( 
            TTimeIntervalMicroSeconds32( KGuardTimerSeconds * KMicroSecondsInSecond ),
            TTimeIntervalMicroSeconds32( KGuardTimerSeconds * KMicroSecondsInSecond ),
            TCallBack( TimerExpired, this ) );
        }
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::State
// -----------------------------------------------------------------------------
//
CSipSystemStateMonitor::TVpnState CSipVpnMonitorAo::State() const
    {
    return iState;
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::EventProcessingCompleted
// -----------------------------------------------------------------------------
//
void CSipVpnMonitorAo::EventProcessingCompleted(
        MSipSystemStateObserver& aObserver )
    {
    if (iState == CSipSystemStateMonitor::EVpnInitiating)
        {
            TInt index = iObservers.Find( &aObserver );
            if ( index >= 0 )
            {
                iCount++;
                if( iObservers.Count() == iCount)
                {
                    iGuardTimer->Cancel();
                    iProperty.Set(KPSVpnSipUid, KVpnSipState, ESipDeregisterCompleted );
                    iCount = 0;
                }
            }
        }
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::EventProcessingCompleted
// -----------------------------------------------------------------------------
//
void CSipVpnMonitorAo::EventProcessingCompleted()
    {
    // SIP deregistration has been completed. Stop the guard timer and tell
    // the VPN client about it.
    iGuardTimer->Cancel();

    iProperty.Set( KPSVpnSipUid, KVpnSipState, ESipDeregisterCompleted );
    iCount = 0;
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::TimerExpired
// -----------------------------------------------------------------------------
//
TInt CSipVpnMonitorAo::TimerExpired(TAny* aSelf)
    {
    // Guard timer expired. Tell VPN client to proceed its work without
    // further waiting.
    CSipVpnMonitorAo* self = reinterpret_cast<CSipVpnMonitorAo*>(aSelf);
    self->EventProcessingCompleted();
    
    return ETrue;
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::RunL
// -----------------------------------------------------------------------------
//
void CSipVpnMonitorAo::RunL()
    {
    TInt state( 0 );  
    
    // VPN client notifies that it has started a VPN session.
    if ( KErrNone == iProperty.Get( state ) )
        {
        if ( MappedState( state ) )
            {
            NotifyObservers();
            }
        }
        
    iProperty.Subscribe( iStatus );
    SetActive();
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::RunError
// -----------------------------------------------------------------------------
//     
TInt CSipVpnMonitorAo::RunError( TInt /*aError*/ )
    {
    return KErrNone; // RunL cannot leave at the moment
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::DoCancel
// -----------------------------------------------------------------------------
//  
void CSipVpnMonitorAo::DoCancel()
    {
    iProperty.Cancel();
    }

// -----------------------------------------------------------------------------
// CSipVpnMonitorAo::MappedState
// -----------------------------------------------------------------------------
//
TBool CSipVpnMonitorAo::MappedState( TInt aState )
    {
    TBool ret = ETrue;
    // Maps P&S key value to VPN state.
    switch( aState )
        {
        case EVpnInitiating:
            iState = CSipSystemStateMonitor::EVpnInitiating;
            break;
        case EVpnTerminated:
            iState = CSipSystemStateMonitor::EVpnTerminated;
            break;
        // Other P&S key values are not mapped to VPN state.
        // Not an error situation.
        default:
            ret = EFalse;
        }
        
    return ret;
    }