keepalive/flextimer/client/src/flexperiodic.cpp
author hgs
Mon, 24 May 2010 20:51:35 +0300
changeset 32 5c4486441ae6
permissions -rw-r--r--
201021

/*
 * 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:  Implementation of CFlexPeriodic class
 *
 */
/*
 * %version: 1 %
 */
// System include files
// User include files go here:
#include "flexperiodic.h"
#include "flextimercommon.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "flexperiodicTraces.h"
#endif

// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// Constructs the object.
// ---------------------------------------------------------------------------
//
EXPORT_C CFlexPeriodic* CFlexPeriodic::NewL( TInt aPriority )
    {

    CFlexPeriodic* self = new ( ELeave ) CFlexPeriodic( aPriority );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------------------------
// Destructs the object.
// ---------------------------------------------------------------------------
//
EXPORT_C CFlexPeriodic::~CFlexPeriodic()
    {
    OstTrace1( TRACE_NORMAL, CFLEXPERIODIC_CFLEXPERIODIC,
            "CFlexPeriodic::~CFlexPeriodic;this=%x", this );

    }

// ---------------------------------------------------------------------------
// Starts the periodic timer. 32-bit delay and interval parameters.
// ---------------------------------------------------------------------------
//
EXPORT_C void CFlexPeriodic::Start( TTimeIntervalMicroSeconds32 aDelay,
                                    TTimeIntervalMicroSeconds32 anInterval,
                                    TCallBack aCallBack,
                                    TCallBack aCallBackError )
    {
    OstTraceExt4( TRACE_NORMAL, CFLEXPERIODIC_START32,
            "CFlexPeriodic::Start32;this=%x;aDelay=%d;"
            "anInterval=%d;aCallBack=%x", ( TUint )this,
            aDelay.Int(), anInterval.Int(), ( TUint )&( aCallBack ) );

    TTimeIntervalMicroSeconds32 zero( 0 );
    __ASSERT_ALWAYS(aDelay >= zero,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicDelayLessThanZero));
    __ASSERT_ALWAYS(anInterval > zero,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicIntervalTooSmall));
    __ASSERT_ALWAYS( aCallBack.iFunction != NULL,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicCallbackFunctionIsNull));
    // aCallBackError is left unasserted on purpose.
    // if error occurs and callback is null client is paniced.

    // Interval value is saved for later use, delay is sent immediately
    // to the server.
    iInterval = MAKE_TINT64( 0, anInterval.Int() );
    iCallBack = aCallBack;
    iCallBackError = aCallBackError;
    CFlexTimer::After( aDelay );
    }

// ---------------------------------------------------------------------------
// Starts the periodic timer. 64-bit delay and interval parameters.
// ---------------------------------------------------------------------------
//
EXPORT_C void CFlexPeriodic::Start( TTimeIntervalMicroSeconds aDelay,
                                    TTimeIntervalMicroSeconds anInterval,
                                    TCallBack aCallBack,
                                    TCallBack aCallBackError )
    {
    OstTraceExt4( TRACE_NORMAL, CFLEXPERIODIC_START64,
            "CFlexPeriodic::Start64;this=%x;aDelay=%lld;"
            "anInterval=%lld;aCallBack=%x", ( TUint )this,
            aDelay.Int64(), anInterval.Int64(), ( TUint )&( aCallBack ) );

    TTimeIntervalMicroSeconds zero( 0 );
    __ASSERT_ALWAYS(aDelay >= zero,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicDelayLessThanZero));
    __ASSERT_ALWAYS(anInterval > zero,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicIntervalTooSmall));
    __ASSERT_ALWAYS( aCallBack.iFunction != NULL,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicCallbackFunctionIsNull));
    // aCallBackError is left unasserted on purpose.
    // if error occurs and callback is null client is paniced.
    
    // Interval value is saved for later use, delay is sent immediately
    // to the server.
    iInterval = anInterval.Int64();
    iCallBack = aCallBack;
    iCallBackError = aCallBackError;
    CFlexTimer::After( aDelay );
    }

// ---------------------------------------------------------------------------
// Configures the flex window sizes for both the initial delay and the
// consequent intervals after that.
// ---------------------------------------------------------------------------
//
EXPORT_C TInt CFlexPeriodic::Configure(
                                 TTimeIntervalMicroSeconds32 aDelayWindow,
                                 TTimeIntervalMicroSeconds32 aIntervalWindow )
    {

    OstTraceExt3( TRACE_NORMAL, CFLEXPERIODIC_CONFIGURE,
            "CFlexPeriodic::Configure32;this=%x;"
            "aDelayWindow=%d;aIntervalWindow=%d", ( TUint )this,
            aDelayWindow.Int(), aIntervalWindow.Int() );

    TTimeIntervalMicroSeconds32 zero( 0 );
    __ASSERT_ALWAYS(aDelayWindow >= zero,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicDelayWindowLessThanZero));
    __ASSERT_ALWAYS(aIntervalWindow >= zero,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicIntervalWindowLessThanZero));

    // interval window is saved for later use. Delay window is sent
    // immediately to server. 
    TInt ret = CFlexTimer::Configure( aDelayWindow );
    if ( ret == KErrNone )
        {
        // Interval window is changed only, if configuration is successful.
        iIntervalWindow = MAKE_TINT64( 0, aIntervalWindow.Int() );
        iSendConfigure = ETrue;
        }
    return ret;
    }

// ---------------------------------------------------------------------------
// Configures the flex window sizes for both the initial delay and the
// consequent intervals after that. 64-bit version.
// ---------------------------------------------------------------------------
//
EXPORT_C TInt CFlexPeriodic::Configure( 
                                   TTimeIntervalMicroSeconds aDelayWindow,
                                   TTimeIntervalMicroSeconds aIntervalWindow )
    {
    OstTraceExt3( TRACE_NORMAL, DUP1_CFLEXPERIODIC_CONFIGURE,
            "CFlexPeriodic::Configure64;this=%x;"
            "aDelayWindow=%lld;aIntervalWindow=%lld", ( TUint )this,
            aDelayWindow.Int64(), aIntervalWindow.Int64() );

    TTimeIntervalMicroSeconds zero( 0 );
    __ASSERT_ALWAYS(aDelayWindow >= zero,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicDelayWindowLessThanZero));
    __ASSERT_ALWAYS(aIntervalWindow >= zero,
            User::Panic(KCFlexPeriodicPanicCat,
                    EFlexPeriodicIntervalWindowLessThanZero));

    // interval window is saved for later use. Delay window is sent
    // immediately to server. 
    TInt ret = CFlexTimer::Configure( aDelayWindow );
    if ( ret == KErrNone )
        {
        // Interval window is changed only, if configuration is successful.
        iIntervalWindow = aIntervalWindow;
        
        // This is set to true only, if the server is able to receive the
        // delay window configuration.
        iSendConfigure = ETrue;
        }
    return ret;
    }

// ---------------------------------------------------------------------------
// Handles the active objects request completion event.
// ---------------------------------------------------------------------------
//
void CFlexPeriodic::RunL()
    {
    if ( KErrNone == iStatus.Int() )
        {
        if ( iSendConfigure )
            {
            OstTrace1( TRACE_NORMAL, CFLEXPERIODIC_RUNL,
                    "CFlexPeriodic::RunL;this=%x", ( TUint )this );
    
            CFlexTimer::Configure( iIntervalWindow );
            // Reset the iSendConfigure to false so that this is sent only once.
            iSendConfigure = EFalse;
            }
        CFlexTimer::After( iInterval );
        iCallBack.CallBack();
        }
    // Error happended in server. timer is not restarted and
    // iCallBackError is called to inform user
    else
        {
        if ( NULL != iCallBackError.iFunction )
            {
            iCallBackError.CallBack();
            }
        // User has not defined iCallBackError
        // Panic client.
        else
            {
            OstTrace1( TRACE_NORMAL, CFLEXPERIODIC_RUNL_PANIC,
            "CFlexPeriodic::RunL;this=%x;"
            "Error returned from FlexTimerServer and no Error CallBack"
            " is defined. Panicing client.", ( TUint )this );
            User::Panic( KCFlexPeriodicPanicCat,
                        EFlexPeriodicErrorCallbackFunctionIsNull );
            }
        }
    }
// ---------------------------------------------------------------------------
// Second part of the two-phase construction.
// ---------------------------------------------------------------------------
//
EXPORT_C void CFlexPeriodic::ConstructL()
    {
    CFlexTimer::ConstructL();

    CActiveScheduler::Add( this );
    }

// ---------------------------------------------------------------------------
// Private constructor with priority.
// ---------------------------------------------------------------------------
//
EXPORT_C CFlexPeriodic::CFlexPeriodic( TInt aPriority ) :
    CFlexTimer( aPriority ), iSendConfigure( EFalse )
    {

    }