--- /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