systemswstubs/ssyreference/src/ssyreferencechannel.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 20:06:52 +0200
changeset 1 ffb8e2ddd8dc
permissions -rw-r--r--
Revision: 201003 Kit: 201003

/*
* 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:  Reference implementation of SSY Channel
*
*/


#include <ssycallback.h>                     // MSsyCallback
#include "ssyreferencechannel.h"
#include "ssyreferencecontrol.h"             // SSY Control
#include "ssyreferencepropertyprovider.h"    // iChannelPropertyProvider
#include "ssyreferencechanneldataprovider.h" // iChannelDataProvider
#include "ssyreferencetrace.h"
#include "ssyreferencecmdhandler.h"


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

// ---------------------------------------------------------------------------
// CSsyReferenceChannel C++ constructor
// ---------------------------------------------------------------------------
//
CSsyReferenceChannel::CSsyReferenceChannel( CSsyReferenceControl& aSsyControl, TSensrvChannelInfo aChannelInfo ) :
    iSsyControl( aSsyControl ),
    iChannelInfo( aChannelInfo ),
    iState( ESsyReferenceChannelIdle )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::CSsyReferenceChannel()" ) ) );
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::CSsyReferenceChannel() - return" ) ) );
    }


// ---------------------------------------------------------------------------
// Symbian 2nd phase constructor
// ---------------------------------------------------------------------------
//
void CSsyReferenceChannel::ConstructL()
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::ConstructL()" ) ) );

    // Create command handler
    iCmdHandler = CSsyReferenceCmdHandler::NewL( *this );
    
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::ConstructL() - return" ) ) );
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::NewL
// ---------------------------------------------------------------------------
//
CSsyReferenceChannel* CSsyReferenceChannel::NewL( CSsyReferenceControl& aSsyControl, TSensrvChannelInfo aChannelInfo )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::NewL()" ) ) );
    CSsyReferenceChannel* self = new ( ELeave ) CSsyReferenceChannel( aSsyControl, aChannelInfo );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::NewL() - return" ) ) );
    return self;
    }

// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CSsyReferenceChannel::~CSsyReferenceChannel()
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::~CSsyReferenceChannel()" ) ) );

    // In case channel is not closed before destruction, providers are not deleted
    if ( iChannelDataProvider )
        {
        delete iChannelDataProvider;
        iChannelDataProvider = NULL;
        }
    
    if ( iChannelPropertyProvider )
        {
        delete iChannelPropertyProvider;
        iChannelPropertyProvider = NULL;
        }

    if ( iCmdHandler )
        {
        delete iCmdHandler;
        iCmdHandler = NULL;
        }

    iProperties.Reset();
    
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::~CSsyReferenceChannel() - return" ) ) );
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::ChannelId
// ---------------------------------------------------------------------------
//
TInt CSsyReferenceChannel::ChannelId()
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::ChannelId() - %i" ), iChannelInfo.iChannelId ) );
    return iChannelInfo.iChannelId;
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::SsyControl
// ---------------------------------------------------------------------------
//
CSsyReferenceControl& CSsyReferenceChannel::SsyControl() const
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::SsyControl()" ) ) );
    return iSsyControl;
    }

// ---------------------------------------------------------------------------
// CSsyReferenceControl::SsyCmdHandler
// ---------------------------------------------------------------------------
//
CSsyReferenceCmdHandler& CSsyReferenceChannel::CommandHandler() const
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::SsyCmdHandler()" ) ) );
    return *iCmdHandler;
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::FindPropertyL
// ---------------------------------------------------------------------------
//
TSensrvProperty& CSsyReferenceChannel::FindPropertyL( 
    const TSensrvPropertyId aPropertyId, 
    TInt aItemIndex,
    TInt aArrayIndex )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::FindPropertyL()" ) ) );
    TSensrvProperty* property = NULL;
    TBool propertyFound( EFalse );

    // Search property
    for ( TInt i = 0; i < iProperties.Count() && !propertyFound; i++ )
        {
        property = static_cast<TSensrvProperty*>( &iProperties[i] );

        // Compare property IDs and array index
        if ( property->GetPropertyId() == aPropertyId )
            {
            // Compare item index if it is given
            if ( ( KErrNotFound == aItemIndex ) || ( property->PropertyItemIndex() == aItemIndex ) )
                {
                // Correct property ID is found, now check is it array type of property.
                // Either array indexes must match or propertys array index has to be array info
                if ( ( property->GetArrayIndex() == aArrayIndex ) || 
                     ( ( property->GetArrayIndex() == ESensrvArrayPropertyInfo ) && 
                       ( ESensrvSingleProperty == aArrayIndex ) ) )
                    {
                    // Correct array index found
                    propertyFound = ETrue;    
                    }
                }
            }
        }

    // Leave if not found
    if ( !propertyFound )
        {
        iSsyControl.FindPropertyL( aPropertyId, aArrayIndex, *property );
        }

    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::FindPropertyL() - return" ) ) );
    return *property;
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::FindAndUpdatePropertyL
// ---------------------------------------------------------------------------
//
void CSsyReferenceChannel::FindAndUpdatePropertyL( const TSensrvProperty& aProperty )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::FindAndUpdatePropertyL()" ) ) );
    TBool propertyFound( EFalse );

    // Search property
    for ( TInt i = 0; i < iProperties.Count() && !propertyFound; i++ )
        {
        // Compare property IDs
        if ( iProperties[i].GetPropertyId() == aProperty.GetPropertyId() )
            {
            // Compare item index if it is given
            if ( ( KErrNotFound != aProperty.PropertyItemIndex() ) && 
                 ( iProperties[i].PropertyItemIndex() == aProperty.PropertyItemIndex() ) )
                {
                // Property found -> update if possible
                if ( iProperties[i].ReadOnly() )
                    {
                    User::Leave( KErrAccessDenied );
                    }
                // If modifiable, get type and update value
                switch ( iProperties[i].PropertyType() )
                    {
                    case ESensrvIntProperty:
                        {
                        TInt value( 0 );
                        aProperty.GetValue( value );
                        iProperties[i].SetValue( value );
                        break;
                        }
                    case ESensrvRealProperty:
                        {
                        TReal value( 0 );
                        aProperty.GetValue( value );
                        iProperties[i].SetValue( (TReal) value );
                        break;
                        }
                    case ESensrvBufferProperty:
                        {
                        TBuf8<20> propValue;
                        aProperty.GetValue( propValue );
                        iProperties[i].SetValue( propValue );
                        break;
                        }
                    default:
                        {
                        break;
                        }
                    }
                propertyFound = ETrue;
                }
            }
        }

    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::FindPropertyL() - return" ) ) );
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::GetProperties
// ---------------------------------------------------------------------------
//
void CSsyReferenceChannel::GetProperties( RSensrvPropertyList& aPropertyList )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::GetProperties()" ) ) );
    // Copy properties one by one to param aPropertyList
    TInt propCount( iProperties.Count() );
    RSensrvPropertyList propList( propCount );

    for ( TInt i = 0; i < propCount; i++ )
        {
        propList.Append( iProperties[i] );
        }

    aPropertyList = propList;
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::GetProperties() - return" ) ) );
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::UpdateState
// ---------------------------------------------------------------------------
//
void CSsyReferenceChannel::UpdateState( const TSsyReferenceChannelState aNewState )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::UpdateState() - %i" ), aNewState ) );
    iState = aNewState;
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::ProcessResponse
// ---------------------------------------------------------------------------
//
void CSsyReferenceChannel::ProcessResponse( TSsyReferenceMsg* aMessage )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::ProcessResponse()" ) ) );
    
    if ( aMessage ) 
        {
        switch ( aMessage->Function() )
            {
            case ESsyReferenceOpenChannelResp:
                {
                // Open channel specific handling here
                TRAPD( err, HandleOpenChannelRespL( aMessage->Error() ) );
                if ( KErrNone != err )
                    {
                    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::ProcessResponse() - Error opening channel: %i" ), err ) );
                    }
                break;
                }
            case ESsyReferenceDataItemReceived:
                {
                // Send data item to data provider
                TRAPD( err, iChannelDataProvider->ChannelDataReceivedL( aMessage ) );
                if ( KErrNone != err )
                    {
                    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::ProcessResponse() - Error receiving data: %i" ), err ) );
                    }
                break;  
                }
            case ESsyReferenceCloseChannelResp:
                {
                // Close channel specific handling here
                HandleCloseChannelResp();
                break;  
                }
            default:
                {
                // This command was not intended to process here, try Control class
                iSsyControl.ProcessResponse( aMessage );    
                COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::ProcessResponse() - Unknown function" ) ) );
                }
            }
        }

    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::ProcessResponse() - return" ) ) );
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::OpenChannel
// ---------------------------------------------------------------------------
//
TInt CSsyReferenceChannel::OpenChannel()
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::OpenChannel()" ) ) );

    TInt err( KErrAlreadyExists );

    // Check that this channel is not already open
    if ( ESsyReferenceChannelIdle == iState )
        {
        // Update state and issue request. Will continue in HandleOpenChannelResp
        UpdateState( ESsyReferenceChannelOpening );

        // Create message with function spesific information
        // and pass it to command handler
        err = iCmdHandler->ProcessCommand( TSsyReferenceMsg( ChannelId(), ESsyReferenceOpenChannel ) );
        }

    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::OpenChannel() - return" ) ) );
    return err;
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::HandleOpenChannelResp
// ---------------------------------------------------------------------------
//
void CSsyReferenceChannel::HandleOpenChannelRespL( const TInt aError )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::HandleOpenChannelResp()" ) ) );

    // Open channel asynhronously and complete request with MSsyCallback::ChannelOpened() when
    // channel is opened.

    // Create instance of the data provider of this channel
    iChannelDataProvider = CSsyReferenceChannelDataProvider::NewL( *this );
    // Create instance of the property provider of this channel
    iChannelPropertyProvider = CSsyReferencePropertyProvider::NewL( *this );

    TInt error( aError );

    // If channel opening succeeds, update state to Open
    if ( KErrNone == aError )
        {
        // Update state to Open
        UpdateState( ESsyReferenceChannelOpen );
        // Get channel properties
        TRAP( error, iSsyControl.SsyConfig().GetChannelPropertiesL( ChannelId(), iProperties ) );
        }
    else
        {
        // Channel opening failed, back to idle
        UpdateState( ESsyReferenceChannelIdle ); 
        }

    // Complete transaction
    iSsyControl.SsyCallback().ChannelOpened( ChannelId(),
                                error,
                                iChannelDataProvider,
                                iChannelPropertyProvider );

    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::HandleOpenChannelResp() - return" ) ) );
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::CloseChannel
// ---------------------------------------------------------------------------
//
TInt CSsyReferenceChannel::CloseChannel()
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::CloseChannel()" ) ) );

    TInt err( KErrNotFound );

    // Check that this channel is open
    if ( ESsyReferenceChannelOpen == iState )
        {
        // Update state and issue request. Will continue in HandleCloseChannelResp
        UpdateState( ESsyReferenceChannelClosing );
        // Create message with function spesific information
        // and pass it to command handler
        err = iCmdHandler->ProcessCommand( TSsyReferenceMsg( ChannelId(), ESsyReferenceCloseChannel ) );
        }

    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::CloseChannel() - return" ) ) );
    return err;
    }

// ---------------------------------------------------------------------------
// CSsyReferenceChannel::HandleCloseChannelResp
// ---------------------------------------------------------------------------
//
void CSsyReferenceChannel::HandleCloseChannelResp()
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::HandleCloseChannelResp()" ) ) );

    // Close channel and complete request with MSsyCallback::ChannelClosed() when
    // channel is closed.

    // Delete providers
    delete iChannelDataProvider;
    iChannelDataProvider = NULL;

    delete iChannelPropertyProvider;
    iChannelPropertyProvider = NULL;

    // Update state to idle
    UpdateState( ESsyReferenceChannelIdle );

    // Reset properties
    iProperties.Reset();

    // Complete transaction
    iSsyControl.SsyCallback().ChannelClosed( ChannelId() );

    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceChannel::HandleCloseChannelResp() - return" ) ) );
    }

// End of file