phoneclientserver/phoneserver/Src/Messenger/CPhSrvMessengerObject.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:15:03 +0100
branchRCL_3
changeset 20 987c9837762f
parent 19 7d48bed6ce0c
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2004 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:  Messenger Object.
*
*/


// INCLUDE FILES

#include "CPhSrvMessengerObject.h"
#include "CPhSrvSubSessionBase.h"
#include "CPhSrvSession.h" // Phone server session.
#include "PhSrvDebugInfo.h"


// CONSTANTS

// Null ID.
const TUint KPhSrvNullId = 0;

// The minimum Default message size.
const TInt KPhSrvMinDefSize = 1;


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


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::CPhSrvMessengerObject
// 
// Constructor.
// -----------------------------------------------------------------------------
//
CPhSrvMessengerObject::CPhSrvMessengerObject( 
    CPhSrvSubSessionBase& aSubSession )
:   iSubSession( aSubSession )
    {
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::~CPhSrvMessengerObject
// 
// Destructor.
// -----------------------------------------------------------------------------
//
CPhSrvMessengerObject::~CPhSrvMessengerObject()
    {
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::ConstructL
// 
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CPhSrvMessengerObject::ConstructL(
    const TPhCltMessengerParameters& aParameters )
    {
    TInt size = aParameters.iDefaultMessageSize;
    if( size < KPhSrvMinDefSize )
        {
        // Default message size must be at least KPhSrvMinDefSize.
        User::Leave( KErrArgument );
        }

    iParameters.iCategoryUid = aParameters.iCategoryUid;
    iParameters.iDefaultMessageSize = size;
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::NewLC
// 
// Static Symbian OS two-phase constructor. Return an instance
// and leave it on the cleanup stack.
// -----------------------------------------------------------------------------
//
CPhSrvMessengerObject* CPhSrvMessengerObject::NewLC(  
    CPhSrvSubSessionBase& aSubSession,
    const TPhCltMessengerParameters& aParameters )
    {
    CPhSrvMessengerObject* self = new( ELeave ) CPhSrvMessengerObject( 
        aSubSession );
    
    CleanupStack::PushL( self );
    self->ConstructL( aParameters );

    return self;
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::InformOfMessengerRequest
// 
// Complete a client request which will indicate the result
// of attempting to perform a request.
// -----------------------------------------------------------------------------
//
void CPhSrvMessengerObject::InformOfMessengerRequest( 
    const TPhCltPhoneResults aResultOfAttemptingRequest,
    const TPhCltMessengerCommand aRequest )
    {
    // Complete the client's pending request, indicating 
    // the result of the messenger request attempt.
    if ( aRequest == EPhCltMesCommandSend )
        {
        // Send command.
        if ( iParameters.iSendDataValid )
            {
            iParameters.iSendStatus.Complete( aResultOfAttemptingRequest );
            iParameters.iSendDataValid = EFalse;
            }
        }
    else if ( aRequest == EPhCltMesCommandReceive )
        {
        // Receive command.
        if ( iParameters.iReceiveDataValid )
            {
            iParameters.iReceiveMessage.Complete( aResultOfAttemptingRequest );
            iParameters.iReceiveDataValid = EFalse;
            }
        }
    else
        {
        // Should never happen!
        }
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::SubSessionHandle
// 
// Return the handle of the subsession that initiated the
// original messenger request.
// -----------------------------------------------------------------------------
//
TInt CPhSrvMessengerObject::SubSessionHandle() const
    {
    return iSubSession.SubSessionUniqueHandle();
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::SetActive
// 
// Set the request active.
// -----------------------------------------------------------------------------
//
void CPhSrvMessengerObject::SetActive( 
    const TPhCltMessengerParameters& aParameters,
    const RMessage2& aMessage,
    const TUint aSentDataId )
    {
    TPhCltMessengerCommand request = aParameters.iMessengerCommand;

    switch( request )
        {
        case EPhCltMesCommandSend:
            {
            // Set the Send data parameters.
            iParameters.iSendStatus = aMessage;
            iParameters.iSendDataValid = ETrue;
            iParameters.iSentDataId = aSentDataId;
            iParameters.iSendPayloadLength = aParameters.iSendPayloadLength;
            break;
            }
        case EPhCltMesCommandReceive:
            {
            // Set the Receive parameters.
            iParameters.iReceiveMessage = aMessage;

            iParameters.iReceiveBufferMaxSize = 
                aParameters.iReceiveBufferMaxSize;

            iParameters.iReceiveDataValid = ETrue;

            // Receive called, so Skip can not be active.
            iParameters.iSkipNextMessage = EFalse;
            iParameters.iSkippedSentDataId = KPhSrvNullId;
            break;
            }
        case EPhCltMesCommandSkip:
            {
            iParameters.iSkipNextMessage = ETrue;
            break;
            }

        default:
            // Should never happen!
            break;
        }
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::IsRequestActive
// 
// Check if there is already active request.
// -----------------------------------------------------------------------------
//
TBool CPhSrvMessengerObject::IsRequestActive( 
    const TPhCltMessengerCommand aRequest ) const
    {
    TBool isRequestActive = EFalse;

    switch( aRequest )
        {
        case EPhCltMesCommandSend:
            {
            isRequestActive = iParameters.iSendDataValid;
            break;
            }
        case EPhCltMesCommandReceive:
            {
            isRequestActive = iParameters.iReceiveDataValid;
            break;
            }
        case EPhCltMesCommandSkip:
            {
            isRequestActive = iParameters.iSkipNextMessage;
            break;
            }

        default:
            // Should never happen!
            break;
        }
    return isRequestActive;
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::IsReadyToReceive
// 
// Check whether this object is ready to receive or not.
// If Receive is active but the length of the buffer 
// -----------------------------------------------------------------------------
//
TBool CPhSrvMessengerObject::IsReadyToReceive( 
    const TDesC8& aSentMessage,
    const TUint aSentDataId )
    {
    TBool ret = EFalse;
    const TInt sendDataLength = aSentMessage.Length();

    ret = IsMessageSkipped( aSentDataId );

      // If the message is not skipped, handle it here.
    if ( !ret )
        {
        // If receive data is valid, then we can be ready to receive.
        if( iParameters.iReceiveDataValid )
            {
            // If the sent message does not fit to receive buffer, then complete
            // Receive to indicate that bigger buffer is needed.
            if ( sendDataLength > 
                 iParameters.iReceiveBufferMaxSize )
                {
                CompleteReceive( aSentMessage, aSentDataId );
                }
            else
                {
                // Object can receive the sent message.
                ret = ETrue;
                }
            }
        }
    return ret;
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::CompleteReceive
// 
// Complete the receive request.
// -----------------------------------------------------------------------------
//
TInt CPhSrvMessengerObject::CompleteReceive(
    const TDesC8& aSentMessage,
    const TUint aSentDataId )
    {
    _DPRINT( 4, "PhSrv.MesObj.CompleteReceive START" );   // debug print

    TBool ret = IsMessageSkipped( aSentDataId );
    TInt err = KErrNotReady;

    // If message is skipped, then we do not complete the request.
    if( ret )
        {
        err = KErrNone;
        }

    // If err is not KErrNone, then receive is handled.
    if ( err != KErrNone )
        {
        // If request is not active, then it can not be completed, and 
        // something has gone wrong. However, recover (do nothing).
        if ( iParameters.iReceiveDataValid )
            {
            // Receive request active, it is handled.

    _DPRINT( 4, "PhSrv.MesObj.CompleteReceive WRITE1" );   // debug print

            const TInt recBufMaxSize = 
                iParameters.iReceiveBufferMaxSize;

            // Write the whole sent message or the beginnig of it to client data
            // area, i.e ensure that receive message buffer is not overflowed.
            iSubSession.Write(
                iParameters.iReceiveMessage,
                1, 
                aSentMessage.Left( recBufMaxSize ) );

            TInt length = aSentMessage.Length();
            TPckgC < TInt > intPckg( length );

    _DPRINT( 4, "PhSrv.MesObj.CompleteReceive WRITE2" );   // debug print

            // Write the length information to user side.
            iSubSession.Write(
                iParameters.iReceiveMessage,
                2, 
                intPckg );

            // If whole sent message was written to receive buffer, then
            // completion was successful.
            if ( length <= recBufMaxSize )
                {
                err = KErrNone;
                }
            else
                {
                // The receive was not completed fully.
                iParameters.iSkippedSentDataId = aSentDataId;
                }

    _DPRINT( 4, "PhSrv.MesObj.CompleteReceive COMPLETE" );   // debug print

            // Complete the receive request.
            if ( !iParameters.iReceiveMessage.IsNull() )
                {
                iParameters.iReceiveMessage.Complete( KErrNone );
                }
            iParameters.iReceiveDataValid = EFalse;
            }
        }

    _DPRINT( 4, "PhSrv.MesObj.CompleteReceive END" );   // debug print

    return err;
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::GetSendDataLength
// 
// Get the Send data.
// -----------------------------------------------------------------------------
//
TInt CPhSrvMessengerObject::GetSendDataLength()
    {
    return iParameters.iSendPayloadLength;
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::GetSendData
// 
// Get the Send data.
// -----------------------------------------------------------------------------
//
void CPhSrvMessengerObject::GetSendData( TDes8& aDes ) const
    {
    // Read the Send data information from user side.
    // Do not leave, but will panic if pointer not valid descriptor.
    iSubSession.Read(
        iParameters.iSendStatus,
        1,
        aDes );
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::GetUid
// 
// Get the Uid.
// -----------------------------------------------------------------------------
//
const TUid& CPhSrvMessengerObject::GetUid() const
    {
    return iParameters.iCategoryUid;
    }


// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::SentDataId
// 
// Get the sent data ID.
// -----------------------------------------------------------------------------
//
TUint CPhSrvMessengerObject::SentDataId()
    {
    return iParameters.iSentDataId;
    }



// -----------------------------------------------------------------------------
// CPhSrvMessengerObject::IsMessageSkipped
// 
// Return information whether the message is skipped or not.
// -----------------------------------------------------------------------------
//
TBool CPhSrvMessengerObject::IsMessageSkipped(
    const TUint aSentDataId )
    {
    TBool ret = EFalse; // By default message is not skipped.

    // If Skip is active, then everything is OK.
    if ( iParameters.iSkipNextMessage )
        {
        // If the sent data is the same as that it was earlier, then it is 
        // skipped. If the sent message is not the same, then it is not skipped.
        if ( iParameters.iSkippedSentDataId == aSentDataId )
            {
            // This message is skipped.
            ret = ETrue;
            }
        else
            {
            // This message is not skipped.
            iParameters.iSkipNextMessage = EFalse;
            iParameters.iSkippedSentDataId = KPhSrvNullId; // Set to not valid.
            }
        }
    return ret;
    }


// End of File