ximpfw/core/srcpscserver/ximpcontextsession.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:54:49 +0200
changeset 0 e6b17d312c8b
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 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:  Context session.
 *
*/

#include "ximpcontextsession.h"
#include "ximpsrvmessage.h"
#include "ximpserverdefs.h"

#include "ximpcontexteventqueue.h"
#include "ximpcontexteventfilter.h"
#include "ximphostmanager.h"
#include "ximpglobals.h"
#include "ximppsccontextimp.h"

#include "ximpfeatureinfoimp.h"
#include "ximpobjecthelpers.h"
#include "ximppanics.h"
#include "ximptrace.h"
#include "ximpoperationdefs.h"
#include "ximpoperationbase.h"

#include "ximphoststates.h"

#include <ximpbase.h>
#include <e32base.h>

using namespace NXIMPSrv;



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

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


// ---------------------------------------------------------------------------
// CXIMPContextSession::~CXIMPContextSession()
// ---------------------------------------------------------------------------
//
CXIMPContextSession::~CXIMPContextSession()
    {
    TRACE_1( _L("CXIMPContextSession[%d]::~CXIMPContextSession()"), this );

    delete iPreparedData;

    if( iEventListenScout )
        {
        iEventListenScout->Complete( KErrCancel );
        delete iEventListenScout;
        }

    iClientData->EventQueue().StopConsuming();

    // Unbind when client has died, and unbind not send.
    CXIMPOperationBase* operation = iClientData->GetCachedUnbind();

    if( operation )
        {
        TRAP_IGNORE(
            {
            CleanupStack::PushL( operation );
            iClientData->AppendToOpQueueL( operation );
            CleanupStack::Pop( operation );
            } );
        }

    iClientData->Close();
    }


// ---------------------------------------------------------------------------
// CXIMPContextSession::CXIMPContextSession()
// ---------------------------------------------------------------------------
//
CXIMPContextSession::CXIMPContextSession()
    {
    TRACE_1( _L("CXIMPContextSession[%d]::CXIMPContextSession()"), this );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::ConstructL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::ConstructL( TUint32 aSessionId )
    {
    iClientData = CXIMPPscContext::NewL( aSessionId );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::TryHandleMessageL()
// From MXIMPSrvSession
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::TryHandleMessageL( MXIMPSrvMessage& aMessage )
    {
    switch( aMessage.Function() )
        {
        //Asynchronous context operations related
        case NRequest::ECtxSsQueueOperation:
            {
            DoQueueOperationL( aMessage );
            break;
            }
        //Asynchronous context operations related
        case NRequest::ECtxSsQueueBindOperation:
            {
            DoQueueOperationL( aMessage );
            break;
            }

        //Event handling related
        case NRequest::ECtxSsInstallEventFilter:
            {
            DoInstallEventFilterL( aMessage );
            break;
            }

        case NRequest::ECtxSsSetEventListenScout:
            {
            DoSetEventListenScoutL( aMessage );
            break;
            }

        case NRequest::ECtxSsCancelEventListenScout:
            {
            DoCancelEventListenScout( aMessage );
            break;
            }

        case NRequest::ECtxSsFetchTopEventDataSize:
            {
            DoFetchTopEventDataSizeL( aMessage );
            break;
            }

        case NRequest::ECtxSsFetchTopEventData:
            {
            DoFetchTopEventDataL( aMessage );
            break;
            }

        case NRequest::ECtxSsFetchTopEventReqId:
            {
            DoFetchTopEventReqIdL( aMessage );
            break;
            }

        case NRequest::ECtxSsDropTopEvent:
            {
            DoDropTopEventL( aMessage );
            break;
            }

        //Synchronous context data access
        case NRequest::ECtxSsPrepareContextFeatures:
            {
            DoPrepareContextFeaturesL( aMessage );
            break;
            }

        case NRequest::ECtxSsGetPreparedData:
            {
            DoGetPreparedDataL( aMessage );
            break;
            }

        default:
            {
            //Unknown request type
            //Nothing to do here.
            }
        }
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::NewEventAvailable()
// From MXIMPEventQueueObserver
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::NewEventAvailable()
    {
    if( iEventListenScout )
        {
        iEventListenScout->Complete( KErrNone );
        delete iEventListenScout;
        iEventListenScout = NULL;
        }
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoQueueOperationL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoQueueOperationL(
    MXIMPSrvMessage& aMessage )
    {
    const TInt operationType = aMessage.Int( MXIMPSrvMessage::Ep0 );

    TPckgBuf< TXIMPRequestId > reqIdBuf;

    // We can take ready unbind from context if it exists.
    CXIMPOperationBase* operation = NULL;
    if( operationType == NXIMPOps::EXIMPUnbindContext )
        {
        operation = iClientData->GetCachedUnbind();
        // ownership transferred
        }

    if( operation )
        {
        // found an unbind, so put it to the queue to be processed
        CleanupStack::PushL( operation );
        iClientData->AppendToOpQueueL( operation );
        reqIdBuf() = operation->RequestId();
        CleanupStack::Pop( operation );
        }
    else
        {
        const TInt pckSize = aMessage.GetDesLengthL( MXIMPSrvMessage::Ep1 );
        HBufC8* paramPck = HBufC8::NewLC( pckSize );
        TPtr8 paramPckPtr = paramPck->Des();
        aMessage.ReadL( MXIMPSrvMessage::Ep1, paramPckPtr );
        reqIdBuf() = iClientData->AddNewOperationL( operationType,
                *paramPck );
        CleanupStack::PopAndDestroy( paramPck );
        }

    aMessage.WriteL( MXIMPSrvMessage::Ep2, reqIdBuf );
    aMessage.Complete( KErrNone );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoInstallEventFilterL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoInstallEventFilterL(
    MXIMPSrvMessage& aMessage )
    {
    const TInt pckSize = aMessage.GetDesLengthL( MXIMPSrvMessage::Ep0 );
    HBufC8* filterPck = HBufC8::NewLC( pckSize );
    TPtr8 filterPckPtr( filterPck->Des() );
    aMessage.ReadL( MXIMPSrvMessage::Ep0, filterPckPtr );

    CXIMPContextEventFilter* newFilter = CXIMPContextEventFilter::NewLC();
    TXIMPObjectPacker< CXIMPContextEventFilter >::UnPackL( *newFilter,
                                                                   *filterPck );

    iClientData->EventQueue().SetEventFilter( *newFilter );
    CleanupStack::Pop( newFilter );
    CleanupStack::PopAndDestroy( filterPck );

    aMessage.Complete( KErrNone );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoSetEventListenScoutL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoSetEventListenScoutL(
    MXIMPSrvMessage& aMessage )
    {
    __ASSERT_ALWAYS( !iEventListenScout,
                     aMessage.PanicClientAndLeaveL(
                     NXIMPPanic::EOnSrvAlreadyListeningEvents ) );

    iClientData->EventQueue().StartConsuming( *this );

    //If there is already a events in que,
    //signal client right a way
    if( iClientData->EventQueue().HasElements() )
        {
        aMessage.Complete( KErrNone );
        }
    else
        {
        aMessage.PlaceOwnershipHere( iEventListenScout );
        }
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoCancelEventListenScout()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoCancelEventListenScout(
    MXIMPSrvMessage& aMessage )
    {
    if( iEventListenScout )
        {
        iEventListenScout->Complete( KErrCancel );
        delete iEventListenScout;
        iEventListenScout = NULL;
        }

    iClientData->EventQueue().StopConsuming();
    aMessage.Complete( KErrNone );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoFetchTopEventDataSizeL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoFetchTopEventDataSizeL(
    MXIMPSrvMessage&  aMessage )
    {
    iClientData->EventQueue().SelectTopEventIfNeededL();
    aMessage.Complete( iClientData->EventQueue().TopEventDataL().Size() );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoFetchTopEventDataL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoFetchTopEventDataL(
    MXIMPSrvMessage& aMessage )
    {
    iClientData->EventQueue().SelectTopEventIfNeededL();
    aMessage.WriteL( MXIMPSrvMessage::Ep0, iClientData->EventQueue().TopEventDataL() );
    aMessage.Complete( KErrNone );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoFetchTopEventReqIdL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoFetchTopEventReqIdL(
    MXIMPSrvMessage& aMessage )
    {
    TPckgBuf< TXIMPRequestId > reqIdBuf;
    
    iClientData->EventQueue().SelectTopEventIfNeededL();
    reqIdBuf() = iClientData->EventQueue().TopEventReqIdL();

    aMessage.WriteL( MXIMPSrvMessage::Ep0, reqIdBuf );
    aMessage.Complete( KErrNone );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoDropTopEventL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoDropTopEventL(
    MXIMPSrvMessage& aMessage )
    {
    iClientData->EventQueue().DropTopEvent();
    aMessage.Complete( KErrNone );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoPrepareContextFeaturesL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoPrepareContextFeaturesL(
    MXIMPSrvMessage& aMessage )
    {
    __ASSERT_ALWAYS( !iPreparedData,
                     aMessage.PanicClientAndLeaveL(
                     NXIMPPanic::EOnSrvAlreadyHavingPrepearedData ) );


    CXIMPFeatureInfoImp* feats = iClientData->FeaturesForSessionLC();
    iPreparedData = TXIMPObjectPacker< CXIMPFeatureInfoImp >::PackL( *feats );
    CleanupStack::PopAndDestroy( feats );

    aMessage.Complete( iPreparedData->Size() );
    }


// -----------------------------------------------------------------------------
// CXIMPContextSession::DoGetPreparedDataL()
// -----------------------------------------------------------------------------
//
void CXIMPContextSession::DoGetPreparedDataL(
    MXIMPSrvMessage& aMessage )
    {
    //Release the prepared data from member variable
    //Buffer gets cleaned even the copying to client side fails
    HBufC8* tmpBuf = iPreparedData;
    iPreparedData = NULL;
    CleanupStack::PushL( tmpBuf );

    //Assert that there is a data to copy to client
    __ASSERT_ALWAYS( tmpBuf,
                     aMessage.PanicClientAndLeaveL(
                     NXIMPPanic::EOnSrvNoPrepearedDataToCopy ) );

    aMessage.WriteL( MXIMPSrvMessage::Ep0, *tmpBuf );

    CleanupStack::PopAndDestroy( tmpBuf );
    aMessage.Complete( KErrNone );
    }


// End of file