sipplugins/sippsystemstatemonitor/src/sipdevicestateaware.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 23 Jun 2010 18:36:31 +0300
changeset 34 3c8db403127f
parent 0 307788aac0a8
permissions -rw-r--r--
Revision: 201023 Kit: 2010125

/*
* Copyright (c) 2007 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:  Class Implementation, aware of Device System State Changes and perform
*                processing related to profile registration/deregistration
*
*/


#include "sipdevicestateaware.h"
#include <sipsystemstateobserver.h>
#include <ssm/ssmdomaindefs.h>
#include <ssm/ssmstate.h>
#include <ssm/ssmsubstates.hrh>
#include <e32std.h> 

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

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

// -----------------------------------------------------------------------------
// CSipDeviceStateAware::ConstructL
// -----------------------------------------------------------------------------
//
void CSipDeviceStateAware::ConstructL()
	{
	iGuardTimer = CPeriodic::NewL( EPriorityNormal );
    //SIP System connects to Domain Id GenMiddlewareDomain3    
    User::LeaveIfError(iStateAwareSession.Connect(KSM2GenMiddlewareDomain3));
    TSsmState currentState = iStateAwareSession.State();
    if(ESsmNormal == currentState.MainState())
        {
        iState = CSipSystemStateMonitor::ESystemReady;
        }
    iStateAwareSession.RequestStateNotification(iStatus);        
    SetActive();
    }

// -----------------------------------------------------------------------------
// CSipDeviceStateAware::CSipDeviceStateAware
// -----------------------------------------------------------------------------
//
CSipDeviceStateAware::CSipDeviceStateAware():CActive(EPriorityStandard)
    {    
    CActiveScheduler::Add(this);
	iState = CSipSystemStateMonitor::ESystemNotReady;
    iCount = 0;
    }

// -----------------------------------------------------------------------------
// CSipDeviceStateAware::~CSipDeviceStateAware
// -----------------------------------------------------------------------------
//
CSipDeviceStateAware::~CSipDeviceStateAware ()
    {
     iGuardTimer->Cancel();
     delete iGuardTimer;
     CActive::Cancel();     
     iObservers.Close();
    }

// -----------------------------------------------------------------------------
// CSipDeviceStateAware::RunL
// Currently this object only monitor for basically three events, Offline, online
// and shutdown. 
// -----------------------------------------------------------------------------
//
void CSipDeviceStateAware::RunL()
    {
	TBool ackAndRequest = ETrue;
    TInt status = iStatus.Int();
    if(KErrNone == status)
        {
            TSsmState currentState = iStateAwareSession.State();
            if(ESsmNormal == currentState.MainState() )
                {                
                switch (currentState.SubState())
                    {
                    // Device is entering into Offline Mode. Hence as part
                    // of staged offline, SIP tries to deregister all profiles.
                    case ESsmNormalRfOffSubState:
                        {
						if(iState == CSipSystemStateMonitor::ESystemOnline)
							{
                       		iState = CSipSystemStateMonitor::ESystemOffline;
                       		NotifyObservers(CSipSystemStateMonitor::ESystemOffline);
							iGuardTimer->Cancel();
							TTimeIntervalMicroSeconds32 time( KGuardTimerSeconds * KMicroSecondsInSecond );
							iGuardTimer->Start( time, time, TCallBack( TimerExpired, this) );                                        
							ackAndRequest = EFalse;
							}
                        break;
                        }
                    //Device entering into online mode, SIP tries to register all
                    //profiles with registration mode 'always on'
                    case ESsmNormalRfOnSubState:
                        {
						if(iState == CSipSystemStateMonitor::ESystemOffline)
							{
                       		NotifyObservers(CSipSystemStateMonitor::ESystemOnline);
							}
                       	iState = CSipSystemStateMonitor::ESystemOnline;
                        break;
                        }
                    default:
                        {                        
                        break;
                        }
                    }//end switch                
                } //end if
			}//end outer if
	if(ackAndRequest)
    	iStateAwareSession.AcknowledgeAndRequestStateNotification(KErrNone, iStatus);
	else
		iStateAwareSession.RequestStateNotification(iStatus);
    SetActive();
    }

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

// -----------------------------------------------------------------------------
// CSipDeviceStateAware::DoCancel
// -----------------------------------------------------------------------------
//
void CSipDeviceStateAware::DoCancel()
    {
    iStateAwareSession.Close();
    }

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

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

// -----------------------------------------------------------------------------
// CSipDeviceStateAware::NotifyObservers
// This function will notify all the observers when the state of the phone changes
// -----------------------------------------------------------------------------
//
void CSipDeviceStateAware::NotifyObservers(
				CSipSystemStateMonitor::TSystemState aState) const
    {
    for ( TInt i = iObservers.Count()-1; i >= 0; i-- )
            {
            iObservers[i]->SystemVariableUpdated( 
                    CSipSystemStateMonitor::ESystemState, 
                    0,
                    aState );
            }
    }

// -----------------------------------------------------------------------------
// CSipDeviceStateAware::TimerExpired
// -----------------------------------------------------------------------------
//
TInt CSipDeviceStateAware::TimerExpired(TAny* aSelf)
    {
	CSipDeviceStateAware* self = reinterpret_cast<CSipDeviceStateAware*>(aSelf);
    self->EventProcessingCompleted();
    return ETrue;
    }

// -----------------------------------------------------------------------------
// CSipDeviceStateAware::EventProcessingCompleted
// -----------------------------------------------------------------------------
//
void CSipDeviceStateAware::EventProcessingCompleted(
        MSipSystemStateObserver& aObserver )
    {
    TInt index = iObservers.Find( &aObserver );
    if ( index >= 0 )
        iCount++;
    if( iObservers.Count() == iCount)
        {
        iGuardTimer->Cancel();
        if(iState == CSipSystemStateMonitor::ESystemOffline)
            {
            iStateAwareSession.AcknowledgeStateNotification(KErrNone);        
            iCount = 0;
            }
        }	
    }

// -----------------------------------------------------------------------------
// CSipDeviceStateAware::EventProcessingCompleted
// -----------------------------------------------------------------------------
//
void CSipDeviceStateAware::EventProcessingCompleted()
    {
    iGuardTimer->Cancel();
    if(iState == CSipSystemStateMonitor::ESystemOffline)
        {
        iStateAwareSession.AcknowledgeStateNotification(KErrNone);   
        iCount = 0;
        }
    }