connectivitylayer/isce/ismpmultiplexer_dll/src/mux.cpp
changeset 0 63b37f68c1ce
child 9 8486d82aef45
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/connectivitylayer/isce/ismpmultiplexer_dll/src/mux.cpp	Fri Nov 06 17:28:23 2009 +0000
@@ -0,0 +1,286 @@
+/*
+* 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 <kernel.h>      // For Kern
+#include <nk_priv.h>      // For __ASSERT_NO_FAST_MUTEX (published to partners)
+
+#include <mmuxtrxif.h>          // For MMuxTrxIf
+#include <mtrxmuxif.h>          // For MTrxMuxIf, E... faults
+
+#include "mmuxlinkif.h"         // For internal MMuxLinkIf
+#include "multiplexer.h"        // For DMultiplexer
+#include "mux.h"                // For DMux
+#include "multiplexertrace.h"   // For C_TRACE..
+#include "memapi.h"             // For MemApi
+
+// Faults
+enum TMuxFaults
+    {
+    EMuxMemAllocFailure = 0x00,
+    EMuxMemAllocFailure2,
+    EMuxNotThreadContext,
+    EMuxNullParam,
+    EMuxNullPtr,
+    EMuxNullPtr2,
+    EMuxInvalidLinkId,
+    };
+
+EXPORT_C MLinkMuxIf* MLinkMuxIf::Register( MMuxLinkIf* aTrx, const TUint8 aTrxId, const TUint8 aLinkId )
+    {
+
+    C_TRACE( ( _T( "MLinkMuxIf::Register 0x%x %d %d<>" ), aTrx, aTrxId, aLinkId ) );
+    __ASSERT_NO_FAST_MUTEX;
+    ASSERT_THREAD_CONTEXT_ALWAYS( ( EMuxNotThreadContext | EDMuxTraceId << KClassIdentifierShift ) );
+    return DMultiplexer::RegisterLink( aTrx, aTrxId, aLinkId );
+
+    }
+
+EXPORT_C MTrxMuxIf* MTrxMuxIf::Register( MMuxTrxIf* aTrx, const TUint8 aTrxId )
+    {
+
+    C_TRACE( ( _T( "MLinkMuxIf::Register 0x%x %d<>" ), aTrx, aTrxId ) );
+    __ASSERT_NO_FAST_MUTEX;
+    MUX_ASSERT_FAULT_MACRO( ( aTrx ), MTrxMuxIf::ENullTrxPointer );
+    MUX_ASSERT_FAULT_MACRO( ( EAmountOfTrxs > aTrxId ), MTrxMuxIf::EInvalidTrxId );
+    MUX_ASSERT_FAULT_MACRO( ( ISTAPI_ASSERT_KERNEL_THREAD_CONTEXT_ALWAYS ), MTrxMuxIf::ENotKernelThreadContext );
+    return DMultiplexer::RegisterTrx( aTrx, aTrxId );
+
+    }
+/*
+* Can be called in different kernel thread contextes.
+*/
+DMux::DMux(
+        const TUint8 aTrxId
+        )
+    {
+
+    C_TRACE( ( _T( "DMux::DMux this 0x%x id %d>" ), this, iShTrxId ) );
+    // Synch with fastMutex, not nested no blocking no allocation, and we need perf.
+    iFastMutex = new NFastMutex();
+    ASSERT_RESET_ALWAYS( iFastMutex, ( EMuxMemAllocFailure | EDMuxTraceId << KClassIdentifierShift ) );
+    NKern::FMWait( iFastMutex );
+    iShTrx = NULL;
+    iShTrxId = aTrxId;
+    for( TInt i( 0 ); i < EMuxAmountOfProtocols; i++ )
+        {
+        iShLinks[ i ] = NULL;
+        }
+    NKern::FMSignal( iFastMutex );
+    C_TRACE( ( _T( "DMux::DMux this 0x%x id %d<" ), this, iShTrxId ) );
+
+    }
+
+/*
+* Deleted by one thread when kernel is shutting down.
+*/
+DMux::~DMux(
+        // None
+        )
+    {
+
+    C_TRACE( ( _T( "DMux::~DMux this 0x%x id %d>" ), this, iShTrxId ) );
+    NKern::FMWait( iFastMutex );
+    iShTrxId = 0x00;
+    iShTrx = NULL;
+    // NULL due no ownership of items
+    for( TInt i( 0 ); i < EMuxAmountOfProtocols; i++ )
+        {
+        iShLinks[ i ] = NULL;
+        }
+    NKern::FMSignal( iFastMutex );
+    // No need to check, if not created already reseted.
+    delete iFastMutex;
+    iFastMutex = NULL;
+    C_TRACE( ( _T( "DMux::~DMux this 0x%x id %d<" ), this, iShTrxId ) );
+
+    }
+
+TUint8 DMux::GetTrxId(
+        // None
+        ) const
+    {
+
+    C_TRACE( ( _T( "DMux::GetTrxId this 0x%x id %d<>" ), this, iShTrxId ) );
+    return iShTrxId;
+
+    }
+
+/*
+* Can be called in different kernel thread contextes.
+*/
+void DMux::SetLink(
+        MMuxLinkIf* aLink,
+        const TUint8 aLinkId
+        )
+    {
+
+    C_TRACE( ( _T( "DMux::SetLink 0x%x this 0x%x id %d %d>" ), aLink, this, aLinkId, iShTrxId ) );
+    __ASSERT_NO_FAST_MUTEX;
+    ASSERT_RESET_ALWAYS( ( aLink ), ( EMuxNullParam | EDMuxTraceId << KClassIdentifierShift ) );
+    ASSERT_RESET_ALWAYS( ( aLinkId < EMuxAmountOfProtocols ), ( EMuxInvalidLinkId | EDMuxTraceId << KClassIdentifierShift ) );
+    NKern::FMWait( iFastMutex );
+    iShLinks[ aLinkId ] = aLink;
+    NKern::FMSignal( iFastMutex );
+    C_TRACE( ( _T( "DMux::SetLink 0x%x 0x%x this 0x%x id %d %d<" ), aLink, this, aLinkId, iShTrxId ) );
+
+    }
+
+/*
+* Most likely called in one kernel thread context, but not limited to one.
+*/
+void DMux::SetTrx(
+        MMuxTrxIf* aTrx
+        )
+    {
+
+    C_TRACE( ( _T( "DMux::SetTrx 0x%x this 0x%x id %d>" ), aTrx, this, iShTrxId ) );
+    __ASSERT_NO_FAST_MUTEX;
+    MUX_ASSERT_FAULT_MACRO( ( aTrx ), MTrxMuxIf::ENullTrxPointer );
+    MUX_ASSERT_FAULT_MACRO( ( !iShTrx ), MTrxMuxIf::ENullTrxPointer );
+    NKern::FMWait( iFastMutex );
+    // Set transceiver first and then notify it's status.
+    iShTrx = aTrx;
+    NotifyTrxStatusChangeToAllLinks( ETrue );
+    NKern::FMSignal( iFastMutex );
+    C_TRACE( ( _T( "DMux::SetTrx 0x%x 0x%x this 0x%x id %d<" ), aTrx, iShTrx, this, iShTrxId ) );
+
+    }
+
+// From MTrxMuxIf start
+
+/*
+* Can be called in different kernel thread contextes.
+*/
+TDes8& DMux::AllocateBlock(
+        const TUint16 aSize
+        )
+    {
+
+    C_TRACE( ( _T( "DMux::AllocateBlock this 0x%x id %d size %d<>" ), this, iShTrxId, aSize ) );
+    __ASSERT_NO_FAST_MUTEX;
+    MUX_ASSERT_FAULT_MACRO( aSize, MTrxMuxIf::EInvalidSize );
+    MUX_ASSERT_FAULT_MACRO( ( ISTAPI_ASSERT_KERNEL_THREAD_CONTEXT_ALWAYS ), MTrxMuxIf::ENotKernelThreadContext );
+    return MemApi::AllocBlock( aSize );
+
+    }
+
+/*
+* Can be called in different kernel thread contextes.
+*/
+void DMux::DeallocateBlock(
+        TDes8& aBlock
+        )
+    {
+
+    C_TRACE( ( _T( "DMux::DeallocateBlock this 0x%x id %d block 0x%x>" ), this, iShTrxId, &aBlock ) );
+    __ASSERT_NO_FAST_MUTEX;
+    MUX_ASSERT_FAULT_MACRO( ( ISTAPI_ASSERT_KERNEL_THREAD_CONTEXT_ALWAYS ), MTrxMuxIf::ENotKernelThreadContext );
+    MemApi::DeallocBlock( aBlock );
+    C_TRACE( ( _T( "DMux::DeallocateBlock this 0x%x id %d block 0x%x<" ), this, iShTrxId, &aBlock ) );
+
+    }
+
+/*
+* Most likely called in one kernel thread context, but not limited to one.
+* Message received from transceiver, should be demultiplexed to appropriate link.
+*/
+void DMux::Receive(
+        TDes8& aMsg,
+        const TUint32 aMuxPacket
+        )
+    {
+
+    C_TRACE( ( _T( "DMux::Receive this 0x%x id %d msg 0x%x aMuxId 0x%x>" ), this, iShTrxId, &aMsg, aMuxPacket ) );
+    const TUint8 protocolId = static_cast<TUint8>( aMuxPacket >> 24 );    // TODO macro
+    Kern::Printf( "protocolId=0x%x", protocolId );// TODO TBR (ToBeRemoved)
+    __ASSERT_NO_FAST_MUTEX;
+    MUX_ASSERT_FAULT_MACRO( ( protocolId < EMuxAmountOfProtocols ), MTrxMuxIf::EInvalidMuxingHeader );
+    MUX_ASSERT_FAULT_MACRO( ( ISTAPI_ASSERT_KERNEL_THREAD_CONTEXT_ALWAYS ), MTrxMuxIf::ENotKernelThreadContext );
+    // TODO ( aMsg.Length() != protocollenght) 
+    NKern::FMWait( iFastMutex );
+    MMuxLinkIf* link = iShLinks[ protocolId ];
+    NKern::FMSignal( iFastMutex );
+    ASSERT_RESET_ALWAYS( ( link ), ( EMuxNullPtr | EDMuxTraceId << KClassIdentifierShift ) );
+    link->Receive( aMsg );
+    C_TRACE( ( _T( "DMux::Receive this 0x%x id %d msg 0x%x aMuxId 0x%x<" ), this, iShTrxId, &aMsg, aMuxPacket ) );
+
+    }
+    
+/*
+* Most likely called in one kernel thread context, but not limited to one.
+*/
+void DMux::Unregister(
+        // None
+        )
+    {
+
+    C_TRACE( ( _T( "DMux::Unregister this 0x%x id %d trx 0x%x>" ), this, iShTrxId, iShTrx ) );
+    __ASSERT_NO_FAST_MUTEX;
+    MUX_ASSERT_FAULT_MACRO( ( iShTrx ), MTrxMuxIf::ETrxNotRegistered );
+    MUX_ASSERT_FAULT_MACRO( ( ISTAPI_ASSERT_KERNEL_THREAD_CONTEXT_ALWAYS ), MTrxMuxIf::ENotKernelThreadContext );
+    NKern::FMWait( iFastMutex );
+    NotifyTrxStatusChangeToAllLinks( EFalse );
+    iShTrx = NULL;
+    NKern::FMSignal( iFastMutex );
+    C_TRACE( ( _T( "DMux::Unregister this 0x%x id %d trx 0x%x<" ), this, iShTrxId, iShTrx ) );
+
+    }
+
+// From MTrxMuxIf end
+
+// From MLinkMuxIf start
+void DMux::Send(
+        TDes8& aMsg,
+        const TUint8 aLinkId,
+        const TMessageSendPriority aPriority
+        )
+    {
+
+    C_TRACE( ( _T( "DMux::Send this 0x%x id %d msg 0x%x aLinkId 0x%x priority %d <>" ), this, iShTrxId, &aMsg, aLinkId, aPriority ) );
+    TUint32 muxId = static_cast<TUint32>( aMsg.Length() | aLinkId << 24 );    // TODO macro 
+    Kern::Printf( "muxId=0x%x", muxId );//TODO TBR
+    ASSERT_RESET_ALWAYS( ( iShTrx ), ( EMuxNullPtr2 | EDMuxTraceId << KClassIdentifierShift ) );
+    iShTrx->Transmit( aMsg, (MMuxTrxIf::TDataTransmitPriority) aPriority, muxId );
+
+    }
+
+// From MLinkMuxIf end
+
+// Internal start
+/*
+* Called with fast mutex held no blocking operations like traces allowed.
+*/
+void DMux::NotifyTrxStatusChangeToAllLinks(
+       TBool aPresent
+       )
+    {
+
+    // TODO: Change status so that it can not be happen send from up and status change from down simultaneously
+    for( TInt i( 0 ); i < EMuxAmountOfProtocols; i++ )
+        {
+        MMuxLinkIf* link = iShLinks[ i ];
+        if( link )
+            {
+            // Link must enque a DFC after this call.
+            link->EnqueTrxPresenceChangedDfc( aPresent );
+            }
+        }
+
+    }
+// Internal start end