connectivitylayer/isce/isaaccessextension_dll/src/pipehandler.cpp
author mikaruus
Tue, 19 Oct 2010 13:16:20 +0300
changeset 9 8486d82aef45
parent 0 63b37f68c1ce
permissions -rw-r--r--
modemadaptation release 2010wk40

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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: 
*
*/



#include <phonetisi.h>              // For ISI_HEADER_OFFSET... defines
#include <pipeisi.h>                // For PNS_PEP..& PNS_PIPE... defines
#include <pipe_sharedisi.h>         // For PN_MULTI_CREDIT_FLOW_CONTROL etc..
#include <pn_const.h>               
#include "pipehandler.h"
#include "pep.h"
#include "iadtrace.h"               // For C_TRACE.. trace macros
#include "internalapi.h"
#include "iadnokiadefinitions.h"
#include "router.h"
#include "iadhelpers.h"             // For GET_.& SET_.. macros
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "pipehandlerTraces.h"
#endif


const TInt KFirstPepIndex( ISI_HEADER_SIZE + PNS_PIPE_CREATE_REQ_OFFSET_FIRSTPEPDEV );
const TInt KFirstPepObj( ISI_HEADER_SIZE + PNS_PIPE_CREATE_REQ_OFFSET_FIRSTPEPOBJ );
//const TInt KFirstPepType( ISI_HEADER_SIZE + PNS_PIPE_CREATE_REQ_OFFSET_FIRSTPEPTYPE );
const TInt KSecondPepIndex( ISI_HEADER_SIZE + PNS_PIPE_CREATE_REQ_OFFSET_SECONDPEPDEV );
const TInt KSecondPepObj( ISI_HEADER_SIZE + PNS_PIPE_CREATE_REQ_OFFSET_SECONDPEPOBJ );
//const TInt KSecondPepType( ISI_HEADER_SIZE + PNS_PIPE_CREATE_REQ_OFFSET_SECONDPEPTYPE );
/*TBR
const TInt KPnMsgReceiver = 1;
const TInt KPnMsgReceiverObject = 6;
*/

DPipeHandler::DPipeHandler(DRouter& aRouter) : iRouter(aRouter)
    {
    OstTrace1( TRACE_NORMAL, DPIPEHANDLER_DPIPEHANDLER_ENTRY, "<>DPipeHandler::DPipeHandler;aRouter=%x", ( TUint )&( aRouter ) );
    C_TRACE( ( _T( "DPipeHandler::DPipeHandler(0x%x) ->" ), &aRouter ) );
    C_TRACE( ( _T( "DPipeHandler::DPipeHandler <-" ) ) );
    }

DPipeHandler::~DPipeHandler()
    {
    OstTrace0( TRACE_NORMAL, DUP1_DPIPEHANDLER_DPIPEHANDLER_ENTRY, ">DPipeHandler::~DPipeHandler" );
    C_TRACE( ( _T( "DPipeHandler::~DPipeHandler ->" ) ) );
    iPepContainer.ResetAndDestroy(); 
    C_TRACE( ( _T( "DPipeHandler::~DPipeHandler <-" ) ) );
    OstTrace0( TRACE_NORMAL, DPIPEHANDLER_DPIPEHANDLER_EXIT, "<DPipeHandler::~DPipeHandler" );
    }
    
void DPipeHandler::ReceivePipeMessage(
        const TDesC8& aMsg,
        MIAD2ChannelApi* aChannel // TODO to ref?
        )
    {
    OstTraceExt2( TRACE_NORMAL, DPIPEHANDLER_RECEIVEPIPEMESSAGE_ENTRY, ">DPipeHandler::ReceivePipeMessage;aMsg=%x;aChannel=%x", ( TUint )&( aMsg ), ( TUint )( aChannel ) );

    C_TRACE( ( _T( "DPipeHandler::ReceivePipeMessage ->" ) ) );
    ASSERT_RESET_ALWAYS( aChannel, EIADNullParameter | EIADFaultIdentifier14 << KFaultIdentifierShift  );
    const TUint8* ptr( aMsg.Ptr() );
    DPep* pep = FindPep( GET_RECEIVER_OBJ( ptr ) ); //FindPep( aMsg );
    if( pep )
        {
        pep->ReceiveMessage( aMsg, aChannel );
        }
    else
        {
        // We are interested only ISA originated pipes that are type of PN_PEP_TYPE_COMMON (a.g.a credit based flowcontrol)
        const TUint8 msgId( ptr[ ISI_HEADER_OFFSET_MESSAGEID ] );
        // TODO: Remove this if pep_type_common to be the only pep_type const TUint8 pepType( ptr[ ISI_HEADER_SIZE + PNS_PEP_CONNECT_REQ_OFFSET_OTHERPEPTYPE ] );
        if( msgId == PNS_PEP_CONNECT_REQ )// TODO: Remove this if pep_type_common to be the only pep_type && pepType == PN_PEP_TYPE_COMMON )
            {
            HandlePepConnectReq( aMsg, aChannel); // creating ISA originated pipe
            }
         else
            {
            aChannel->ReceiveMsg(aMsg);
            }
        }
    C_TRACE( ( _T( "DPipeHandler::ReceivePipeMessage <-" ) ) );
    OstTrace0( TRACE_NORMAL, DPIPEHANDLER_RECEIVEPIPEMESSAGE_EXIT, "<DPipeHandler::ReceivePipeMessage" );
    }

TInt DPipeHandler::SendPipeMessage(
        TDes8& aMsg,
        TUint16 aFromChannel
        )
    {
    OstTraceExt2( TRACE_NORMAL, DPIPEHANDLER_SENDPIPEMESSAGE_ENTRY, ">DPipeHandler::SendPipeMessage;aMsg=%x;aFromChannel=%hx", ( TUint )&( aMsg ), aFromChannel );

    C_TRACE( ( _T( "DPipeHandler::SendPipeMessage from: %d ->" ), aFromChannel ) );
    TInt retVal( KErrNone );
    const TUint8* ptr( const_cast<TUint8*>( aMsg.Ptr() ) );
    DPep* pep = FindPep( GET_SENDER_OBJ( ptr ) );
    if( pep )
        {
        retVal = pep->SendMessage( aMsg, aFromChannel ); // is this aFromChannel needed?
        }
    else
        {
        switch( ptr[ ISI_HEADER_OFFSET_MESSAGEID ] )
            {
            case PNS_PIPE_DATA:
                {
                TRACE_ASSERT_INFO( 0, (TUint8)aFromChannel<<KChannelNumberShift );
                retVal = KErrNotFound;
                break;
                }
            case PNS_PIPE_CREATE_REQ:
                {
                retVal = HandlePipeCreateReq( aMsg, aFromChannel );
                break;
                }
            default:
                {
                retVal = iRouter.SendMsg( aMsg );
                break;
                }
            }
        }
    C_TRACE( ( _T( "DPipeHandler::SendPipeMessage 0x%x <-" ), retVal ) );
    
    OstTrace1( TRACE_NORMAL, DPIPEHANDLER_SENDPIPEMESSAGE_EXIT, "<DPipeHandler::SendPipeMessage;retVal=%d", retVal );
    return retVal;
    }

void DPipeHandler::HandlePepConnectReq(
        const TDesC8& aMsg,
        MIAD2ChannelApi* aChannel
        )
    {
    OstTraceExt2( TRACE_NORMAL, DPIPEHANDLER_HANDLEPEPCONNECTREQ_ENTRY, ">DPipeHandler::HandlePepConnectReq;aMsg=%x;aChannel=%x", ( TUint )&( aMsg ), ( TUint )( aChannel ) );

    C_TRACE( ( _T( "DPipeHandler::HandlePepConnectReq ->" ) ) );
    ASSERT_RESET_ALWAYS( aChannel, EIADNullParameter | EIADFaultIdentifier15 << KFaultIdentifierShift );
    const TUint8* ptr( const_cast<TUint8*>( aMsg.Ptr() ) );
    TUint16 receiverObj = GET_RECEIVER_OBJ( ptr );
    ASSERT_RESET_ALWAYS( KErrNone == CreatePep( receiverObj, EFalse), ( receiverObj << KChannelNumberShift ) );
    // TODO change DPep to get & not a * IST
    DPep* temp = FindPep( receiverObj );
    ASSERT_RESET_ALWAYS( temp, 0 );
    temp->ReceiveMessage( aMsg, aChannel);	
    C_TRACE( ( _T( "DPipeHandler::HandlePepConnectReq pepcontainer c %d" ), iPepContainer.Count() ) );
    C_TRACE( ( _T( "DPipeHandler::HandlePepConnectReq <-" ) ) );

    OstTrace1( TRACE_NORMAL, DPIPEHANDLER_HANDLEPEPCONNECTREQ_EXIT, "<DPipeHandler::HandlePepConnectReq;iPepContainer.Count()=%d", iPepContainer.Count() );
    }


TInt DPipeHandler::HandlePipeCreateReq( TDes8& aMessage, TUint16 aFromChannel )
    {
    OstTraceExt2( TRACE_NORMAL, DPIPEHANDLER_HANDLEPIPECREATEREQ_ENTRY, ">DPipeHandler::HandlePipeCreateReq;aMessage=%x;aFromChannel=%hx", ( TUint )&( aMessage ), aFromChannel );

    C_TRACE( ( _T( "DPipeHandler::HandlePipeCreateReq from: %d ->" ), aFromChannel ) );

    const TUint8* tmpPtr( aMessage.Ptr() );
    ASSERT_RESET_ALWAYS( aMessage.Length() > KSecondPepObj, EIADOverTheLimits | EIADFaultIdentifier13 << KFaultIdentifierShift );
    TUint8 firstPepDev = ( tmpPtr[ KFirstPepIndex ] & 0xFC );//OK
    TUint16 firstPepObj = IS_DEV_HOST( tmpPtr[ KFirstPepIndex ] ) ? 
                          ( ((TUint16)tmpPtr[ KFirstPepObj ] ) + (( firstPepDev & 0x0F ) << 8) ) :
                          ( ((TUint16)tmpPtr[ KFirstPepObj ] ) + (( firstPepDev & 0x03 ) << 8) );
    TUint8 secondPepDev = ( tmpPtr[ KSecondPepIndex ] & 0xFC );//OK
    TUint16 secondPepObj = IS_DEV_HOST( tmpPtr[ KSecondPepIndex ] ) ?
                           ( ((TUint16)tmpPtr[ KSecondPepObj ]) + (( secondPepDev & 0x0F ) << 8 ) ) :
                           ( ((TUint16)tmpPtr[ KSecondPepObj ]) + (( secondPepDev & 0x03 ) << 8 ) );
    TRACE_ASSERT_INFO( firstPepDev == THIS_DEVICE || firstPepDev == OTHER_DEVICE_1, (TUint8)aFromChannel<<KChannelNumberShift | firstPepDev );
    TRACE_ASSERT_INFO( secondPepDev == THIS_DEVICE || secondPepDev == OTHER_DEVICE_1, (TUint8)aFromChannel<<KChannelNumberShift | secondPepDev );

    C_TRACE((_T("DIscIsiPipeHandler::HandlePipeCreateReq StateAfterCreate 0x%x"), tmpPtr[ ISI_HEADER_SIZE + PNS_PIPE_CREATE_REQ_OFFSET_STATEAFTERCREATION ] ) );
    C_TRACE((_T("DIscIsiPipeHandler::HandlePipeCreateReq Priority 0x%x"), tmpPtr[ ISI_HEADER_SIZE + PNS_PIPE_CREATE_REQ_OFFSET_PRIORITY ] ) );
    C_TRACE((_T("DIscIsiPipeHandler::HandlePipeCreateReq 1stPepDev 0x%x"), firstPepDev));
    C_TRACE((_T("DIscIsiPipeHandler::HandlePipeCreateReq 1stPepObj 0x%x"), firstPepObj));
    C_TRACE((_T("DIscIsiPipeHandler::HandlePipeCreateReq 2ndPepDev 0x%x"), secondPepDev));
    C_TRACE((_T("DIscIsiPipeHandler::HandlePipeCreateReq 2ndPepObj 0x%x"), secondPepObj));
    
    OstTraceExt5( TRACE_NORMAL, DPIPEHANDLER_HANDLEPIPECREATEREQ, "DPipeHandler::HandlePipeCreateReq;StateAfterCreate=%hhx;firstPepDev=%hhx;firstPepObj=%hhx;secondPepDev=%hhx;secondPepObj=%hhx", 
    			tmpPtr[ ISI_HEADER_SIZE + PNS_PIPE_CREATE_REQ_OFFSET_STATEAFTERCREATION ], firstPepDev, firstPepObj, secondPepDev, secondPepObj );

    

    TInt retVal(KErrNone);
    if( firstPepDev == THIS_DEVICE )
        {
        if( aFromChannel == firstPepObj )
            {
            retVal = CreatePep( firstPepObj, ETrue );
            C_TRACE( ( _T( "DPipeHandler::HandlePipeCreateReq CreatePep sender=1st pepobj (controller) retVal %d" ), aFromChannel ) );
            OstTraceExt1( TRACE_NORMAL, DUP1_DPIPEHANDLER_HANDLEPIPECREATEREQ, "DPipeHandler::HandlePipeCreateReq CreatePep sender=1st pepobj (controller);channelId=%hx", aFromChannel );
            
            }
        else
            {
            retVal = CreatePep( firstPepObj, EFalse );
            C_TRACE( ( _T( "DPipeHandler::HandlePipeCreateReq CreatePep 1st retVal %d" ), aFromChannel ) );
            OstTraceExt1( TRACE_NORMAL, DUP2_DPIPEHANDLER_HANDLEPIPECREATEREQ, "DPipeHandler::HandlePipeCreateReq CreatePep 1st;channelId=%hx", aFromChannel );
            
            }
        }
    if( retVal != KErrNone )
        {
        TRACE_ASSERT_INFO( 0, (TUint8)aFromChannel<<KChannelNumberShift );
        return retVal;//TODO: remove multiple return points
        }

    if( secondPepDev == THIS_DEVICE )
        {
        if( aFromChannel == secondPepObj )
            {
            retVal = CreatePep( secondPepObj, ETrue );
            C_TRACE( ( _T( "DPipeHandler::HandlePipeCreateReq CreatePep sender=2nd pepobj (controller) retVal %d" ), aFromChannel ) );
            OstTraceExt1( TRACE_NORMAL, DUP3_DPIPEHANDLER_HANDLEPIPECREATEREQ, "DPipeHandler::HandlePipeCreateReq CreatePep sender=2nd pepobj (controller);channelId=%hx", aFromChannel );
            
            }
        else
            {
            retVal = CreatePep( secondPepObj, EFalse );
            C_TRACE( ( _T( "DPipeHandler::HandlePipeCreateReq CreatePep 2nd retVal %d" ), aFromChannel ) );
            OstTraceExt1( TRACE_NORMAL, DUP4_DPIPEHANDLER_HANDLEPIPECREATEREQ, "DPipeHandler::HandlePipeCreateReq CreatePep 2nd ;channelId=%hx", aFromChannel );
            
            }
        }
    if( retVal != KErrNone )
        {
        TRACE_ASSERT_INFO( 0, (TUint8)aFromChannel<<KChannelNumberShift );
        return retVal;//TODO: remove multiple return points
        }
    // forward to ISA
    C_TRACE( ( _T( "DPipeHandler::HandlePipeCreateReq CreatePep TBR sending...%d %d" ), aMessage.Length(), aMessage.MaxLength() ) );
    retVal = iRouter.SendMsg( aMessage );
    C_TRACE( ( _T( "DPipeHandler::HandlePipeCreateReq return: %d <-" ), retVal ) );

    OstTrace1( TRACE_NORMAL, DUP5_DPIPEHANDLER_HANDLEPIPECREATEREQ_EXIT, "<DPipeHandler::HandlePipeCreateReq;retVal=%d", retVal );
    return retVal;
    }

TInt DPipeHandler::CreatePep(
        TUint16 aPepChannel,
        TBool aIsController
        )
    {
    OstTraceExt2( TRACE_NORMAL, DPIPEHANDLER_CREATEPEP_ENTRY, ">DPipeHandler::CreatePep;aPepChannel=%hx;aIsController=%d", aPepChannel, aIsController );

    C_TRACE( ( _T( "DPipeHandler::CreatePep 0x%x %d ->" ), aPepChannel, aIsController ) );
    TInt retVal( KErrNone );
    MIAD2ChannelApi* channel = iRouter.GetChannel( aPepChannel );
    if( channel )
        {
        DPep* tmp = NULL;
        tmp = new DPep( &iRouter, channel, aPepChannel, *this );
        ASSERT_RESET_ALWAYS( tmp, EIADMemoryAllocationFailure | EIADFaultIdentifier24 << KFaultIdentifierShift  ); 
        iPepContainer.Append( tmp );
        C_TRACE( ( _T( "DPipeHandler::CreatePep pepcontainer c %d" ), iPepContainer.Count() ) );
        OstTrace1( TRACE_NORMAL, DPIPEHANDLER_CREATEPEP, "DPipeHandler::CreatePep;iPepContainer.Count()=%d", iPepContainer.Count() );
        
        
        }
    else
        {
        C_TRACE( ( _T( "DPipeHandler::CreatePep channel not open" ) ) );
        OstTraceExt1( TRACE_NORMAL, DUP1_DPIPEHANDLER_CREATEPEP, "DPipeHandler::CreatePep;aPepChannel=%hx", aPepChannel );
        
        retVal = KErrGeneral;
        TRACE_ASSERT_INFO( 0, aPepChannel << KChannelNumberShift );        
        }
    C_TRACE( ( _T( "DPipeHandler::CreatePep 0x%x %d &d <-" ), aPepChannel, aIsController, retVal ) );

    OstTrace1( TRACE_NORMAL, DPIPEHANDLER_CREATEPEP_EXIT, "<DPipeHandler::CreatePep;retVal=%d", retVal );
    return retVal;
    }

void DPipeHandler::RemovePep(
        DPep* aPep
        )
    {
    OstTrace1( TRACE_NORMAL, DPIPEHANDLER_REMOVEPEP_ENTRY, ">DPipeHandler::RemovePep;aPep=%x", ( TUint )( aPep ) );

    C_TRACE( ( _T( "DPipeHandler::RemovePep 0x%x ->" ), aPep ) );
    TInt ind = iPepContainer.Find( aPep );
    if( KErrNotFound != ind )
        {
        iPepContainer.Remove( ind );
        C_TRACE( ( _T( "DPipeHandler::RemovePep pepcontainer c %d" ), iPepContainer.Count() ) );
        OstTrace1( TRACE_NORMAL, DPIPEHANDLER_REMOVEPEP, "DPipeHandler::RemovePep;iPepContainer.Count()=%d", iPepContainer.Count() );
        
        delete aPep;
        aPep = NULL;
        if( iPepContainer.Count() == 0 )
            {
            iPepContainer.Compress();
            iPepContainer.Reset();
            }
        }
    else
        {
        TRACE_ASSERT_ALWAYS;
        }
    C_TRACE( ( _T( "DPipeHandler::RemovePep 0x%x <-" ), aPep ) );

    OstTrace0( TRACE_NORMAL, DPIPEHANDLER_REMOVEPEP_EXIT, "<DPipeHandler::RemovePep" );
    }

DPep* DPipeHandler::FindPep(
        const TUint16 aChannelId
        )
    {
    OstTraceExt2( TRACE_NORMAL, DPIPEHANDLER_FINDPEP_ENTRY, ">DPipeHandler::FindPep;aChannelId=%hx;iPepContainer.Count()=%d", aChannelId, iPepContainer.Count() );

    DPep* pep( NULL );
    TInt count( iPepContainer.Count() );
    C_TRACE( ( _T( "DPipeHandler::FindPep 0x%x %d ->" ), aChannelId, count ) );

	  for( TInt i( count - 1 ); i >= 0; --i )
		    {
		    if( iPepContainer[ i ]->ChannelId() == aChannelId )
			     {
			     pep = iPepContainer[ i ];
			     break;
			     }
        }
    C_TRACE( ( _T( "DPipeHandler::FindPep 0x%x 0x%x <-" ), aChannelId, pep ) );
    
    OstTrace1( TRACE_PIPE, DPIPEHANDLER_FINDPEP_EXIT, "<DPipeHandler::FindPep;pep=%x", (TUint)(pep) );
    return pep;
    }

#if (NCP_COMMON_SOS_VERSION_SUPPORT >= SOS_VERSION_95)
void DPipeHandler::PipeLoaned(
        const TUint16 aLoanerChannel,
        MIAD2ChannelApi* aCh
        )
    {

    C_TRACE( ( _T( "DPipeHandler::PipeLoaned 0x%x ->" ), aLoanerChannel ) );
    OstTrace1( TRACE_PIPE, DPIPEHANDLER_PIPELOANED_ENTRY, ">DPipeHandler::PipeLoaned;loanerChannel=%x", (TUint)aLoanerChannel );
    DPep* pep = FindPep( aLoanerChannel );
    if( pep )
        {
        pep->SetLoaned( aCh );
        }
    else
        {
        TRACE_ASSERT_ALWAYS;
        }
    OstTrace1( TRACE_PIPE, DPIPEHANDLER_PIPELOANED_EXIT, "<DPipeHandler::PipeLoaned;loanerChannel=%x", (TUint)aLoanerChannel );
    C_TRACE( ( _T( "DPipeHandler::PipeLoaned 0x%x <-" ), aLoanerChannel ) );

    }

void DPipeHandler::PipeLoanReturned(
        const TUint16 aLoanerChannel,
        MIAD2ChannelApi* aOldCh
        )
    {

    C_TRACE( ( _T( "DPipeHandler::PipeLoanReturned 0x%x ->" ), aLoanerChannel ) );
    DPep* pep = FindPep( aLoanerChannel );
    if( pep )
        {
        pep->SetLoanReturned( aOldCh );
        }
    else
        {
        TRACE_ASSERT_ALWAYS;
        }
    C_TRACE( ( _T( "DPipeHandler::PipeLoanReturned 0x%x <-" ), aLoanerChannel ) );

    }

#endif