systemswstubs/examplecommonisc/IscDriver/src/IscMainRcvBuffer.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 14 Jan 2010 07:14:53 +0200
changeset 0 0ce1b5ce9557
permissions -rw-r--r--
Revision: 201001

/*
* Copyright (c) 2005 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:  An example implementation for ISC Driver Reference
*
*/



// INCLUDE FILES
#include <IscDefinitions.h>
#include <IscMultiplexerBase.h>
#include "IscMainRcvBuffer.h"
#include "IscQueue.h"
#include "IscDevice.h"
#include "IscChannel.h"
#include "IscChannelContainer.h"
#include "IscTrace.h"


// EXTERNAL DATA STRUCTURES

// EXTERNAL FUNCTION PROTOTYPES  

// CONSTANTS
DIscMainRcvBuffer* DIscMainRcvBuffer::iThisPointer = NULL;
const TInt KBufferCleanUpDfcPriority( 4 );

// MACROS

// LOCAL CONSTANTS AND MACROS

// MODULE DATA STRUCTURES

// LOCAL FUNCTION PROTOTYPES

// FORWARD DECLARATIONS


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

// -----------------------------------------------------------------------------
// DIscMainRcvBuffer::DIscMainRcvBuffer
// C++ default constructor
// ( other items were commented in a header ).
// -----------------------------------------------------------------------------
//
DIscMainRcvBuffer::DIscMainRcvBuffer( DIscDevice *aDevice, TUint16 aIscMainRcvBufferQueueSize )
    :iDevice ( aDevice ),
     iDfc( NULL ),
     iMainRcvBufferQueue( NULL )
    {
    iIscMainRcvBufferQueueSize = aIscMainRcvBufferQueueSize;
    iMainRcvBuffer = new TUint32*[iIscMainRcvBufferQueueSize];
    ASSERT_RESET_ALWAYS( iMainRcvBuffer, "IscDriver",EIscMemoryAllocationFailure );

    for ( TInt i = 0; i < iIscMainRcvBufferQueueSize; i++ )
        {
        iMainRcvBuffer[i] = NULL;
        }
    }


// -----------------------------------------------------------------------------
// DIscMainRcvBuffer::DoCreate
// Second-phase constructor to complete construction.
// ( other items were commented in a header ).
// -----------------------------------------------------------------------------
//
void DIscMainRcvBuffer::DoCreate()
    {
    if ( iThisPointer ) //Only one instance of this class is allowed
        {
        ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscMainRcvBufferInitialize );
        }

    iDfc = new TDfc( BufferCleanUp, this, Kern::DfcQue0(), KBufferCleanUpDfcPriority );
    ASSERT_RESET_ALWAYS( iDfc, "IscDriver",EIscMemoryAllocationFailure );
    
    iMainRcvBufferQueue = new DIscQueue( iMainRcvBuffer, iIscMainRcvBufferQueueSize );
    ASSERT_RESET_ALWAYS( iMainRcvBufferQueue, "IscDriver",EIscMemoryAllocationFailure );

    //Store pointer of this instance that can be used from static functions
    iThisPointer = this;
    }

//Destructor
DIscMainRcvBuffer::~DIscMainRcvBuffer()
    {
    delete iDfc;
    delete iMainRcvBufferQueue;
    iDfc = NULL;
    iMainRcvBufferQueue = NULL;
    iThisPointer = NULL;
    iDevice = NULL;
    }

// -----------------------------------------------------------------------------
// DIscMainRcvBuffer::MsgReceive
// Function that should be called to store incoming frame
// ( other items were commented in a header ).
// -----------------------------------------------------------------------------
//
void DIscMainRcvBuffer::MsgReceive( TDesC8* aData )
    {    
    E_TRACE( ( _T( "IMRB:MR(0x%x)" ), aData ) );
    //Check that instance of this class is created
    if ( !iThisPointer )
        {
        // MainRcvBuffer not initialized -> panic
        ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscMainRcvBufferInitialize );
        }
    
    TInt r = iThisPointer->iMainRcvBufferQueue->Add( aData );
    ASSERT_RESET_ALWAYS( r == KErrNone, "IscDriver",EIscMainRcvBufferOverflow );
    iThisPointer->AddDfc();
    }

// -----------------------------------------------------------------------------
// DIscMainRcvBuffer::AddDfc
// Function for adding Dfc
// ( other items were commented in a header ).
// -----------------------------------------------------------------------------
//
void DIscMainRcvBuffer::AddDfc()
    {    
#ifndef __WINS__
    if ( NKern::CurrentContext() == NKern::EInterrupt )
        {
        iDfc->Add();
        }
    else
        {
        iDfc->Enque();
        }
#else
    // Have to do DoEnque since Enque() & Add() cannot be called from pure 
    // win32 thread context. And this call might come directly in win32 thread
    // since the implementation of ISC Data Transmission API can do virtually 
    // anything in WINS
    iDfc->DoEnque();
#endif
    }

// -----------------------------------------------------------------------------
// DIscMainRcvBuffer::BufferCleanUp
// Function to empty messages in main buffer
// ( other items were commented in a header ).
// -----------------------------------------------------------------------------
//
void DIscMainRcvBuffer::BufferCleanUp( TAny* aPtr )
    {
    C_TRACE( ( _T( "DIscMainRcvBuffer::BufferCleanUp(0x%x)" ), aPtr ) );
    
    DIscMainRcvBuffer* Buffer = ( DIscMainRcvBuffer* )aPtr;
    
    
    TUint16 rcvChannelId( KIscFrameReceiverNotFound );
    TAny* channelPtr = NULL;
    DIscChannel* tempPtr = NULL;
    TBool channelFound( EFalse );

    TDesC8* ptr = NULL;
    ptr = ( TDesC8* )Buffer->iMainRcvBufferQueue->RemoveFirst();
        
    while ( ptr )
        {
        Buffer->iDevice->iIscMultiplexerInterface->GetRcvChannelId( *ptr, rcvChannelId, channelPtr );
    
        C_TRACE( ( _T( "DIscMainRcvBuffer::BufferCleanUp channelId (0x%x) channelPtr (0x%x)" ), rcvChannelId, channelPtr ) );
        if ( rcvChannelId >= KIscFirstChannel &&  rcvChannelId < KIscNumberOfUnits && channelPtr )
            {
            channelFound = EFalse;
            for ( TUint16 i( 0 ); ( i < KIscMaxNumberOfChannelSharers ) && ( !channelFound ); i++ )
                {
                tempPtr = IscChannelContainer::Channel( rcvChannelId, i );
                if ( tempPtr == channelPtr )
                    {
                    // correct channel found
                    ( ( DIscChannel* )channelPtr )->StoreFrame( ptr );
                    channelFound = ETrue;
                    }
                tempPtr = NULL;
                }
            if ( !channelFound )
                {
                TRACE_ASSERT_ALWAYS;
                // correct channel was not found -> release frame
                Buffer->iDevice->ReleaseMemoryBlock( ( TDes8* ) ptr );
                }
            }
        else if ( rcvChannelId == KIscFrameReceiverNotFound )
            {
            C_TRACE( ( _T( "DIscMainRcvBuffer::BufferCleanUp Frame Receiver not found!" ) ) );
            Buffer->iDevice->ReleaseMemoryBlock( ( TDes8* ) ptr );
            }
        // Frame going to control channel
        else if ( rcvChannelId == 0x00 )
            {
            Buffer->iDevice->iIscMultiplexerInterface->HandleControlFrame( *ptr );
            }
        else
            {
            TRACE_ASSERT_ALWAYS;
            Buffer->iDevice->ReleaseMemoryBlock( ( TDes8* ) ptr );
            }

        // get the next frame from the queue
        ptr = ( TDes8* )Buffer->iMainRcvBufferQueue->RemoveFirst();
        }

    IscChannelContainer::ChannelComplition( NULL );

    C_TRACE( ( _T( "DIscMainRcvBuffer::BufferCleanUp - return 0x%x" ) ) );

    }

// ========================== OTHER EXPORTED FUNCTIONS =========================

//  End of File