connectivitylayer/isce/ismpmultiplexer_dll/src/multiplexer.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 <kernel.h>      // For Kern
#include <kern_priv.h>   // For DMutex

#include <mmuxtrxif.h>          // For MMuxTrxIf
#include <mtrxmuxif.h>          // For MTrxMuxIf, EMultiplexer... faults

#include "multiplexer.h"        // For DMultiplexer
#include "mux.h"                // For DMux
#include "multiplexertrace.h"   // For C_TRACE..

// Faults
enum TMultiplexerFaults
    {
    EMultiplexerMemAllocFailure = 0x00,
    EMultiplexerMemAllocFailure2,
    EMultiplexerNullParam,
    EMultiplexerInvalidTrxId,
    EMultiplexerMutexCreateFailed,
    EMultiplexerMutexWaitFailed,
    };

// CONSTS
DMux* DMultiplexer::iShMultiplexers[ EAmountOfTrxs ] = { NULL };
DMutex* DMultiplexer::iShMultiplexersMutex = NULL;
_LIT8( KMultiplexerMutex, "KMultiplexerMutex" );

DMultiplexer::DMultiplexer(
        // None
        )
    {

    C_TRACE( ( _T( "DMultiplexer::DMultiplexer>" ) ) );
    // We need DMutex because lock is held while allocating memory and we do not have strict perf requirements for registerings.
    TInt err( Kern::MutexCreate( iShMultiplexersMutex, KMultiplexerMutex, KMutexOrdGeneral0 ) );
    ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EMultiplexerMutexCreateFailed | EDMultiplexerTraceId << KClassIdentifierShift ) );
    // No need to protect cause done only from one thread.
    for( TInt i( 0 ); i < EAmountOfTrxs; i++ )
        {
        iShMultiplexers[ i ] = NULL;
        }
    C_TRACE( ( _T( "DMultiplexer::DMultiplexer<" ) ) );

    }

DMultiplexer::~DMultiplexer(
        // None
        )
    {

    C_TRACE( ( _T( "DMultiplexer::~DMultiplexer>" ) ) );
    // No protection needed, cause done only when kernel restarts and from one thread.
    for( TInt i( 0 ); i < EAmountOfTrxs; i++ )
        {
        DMux* temp = iShMultiplexers[ i ];
        delete temp;
        temp = NULL;
        iShMultiplexers[ i ] = NULL;
        }
        
    if ( iShMultiplexersMutex )
        {
        iShMultiplexersMutex->Close( NULL );
        }
        
    C_TRACE( ( _T( "DMultiplexer::~DMultiplexer<" ) ) );

    }

/*
* Registers a transceiver with unique transceiver identifier to multiplexer.
* Returns an interface to transceiver to use multiplexer services.
*/
MTrxMuxIf* DMultiplexer::RegisterTrx(
        MMuxTrxIf* aTrx,
        const TUint8 aTrxId
        )
    {

    C_TRACE( ( _T( "DMultiplexer::RegisterTrx 0x%x id %d>" ), aTrx, aTrxId ) );
    DMux* mux = GetMuxForTrx( aTrxId );
    mux->SetTrx( aTrx );
    C_TRACE( ( _T( "DMultiplexer::RegisterTrx 0x%x id %d mux 0x%x<" ), aTrx, aTrxId, mux ) );
    return mux;

    }

/*
* Registers a link with unique link identifier to multiplexer to send and receive data through
* transceiver identified with unique transceiver id.
* Returns an interface to link to use multiplexer services.
*/
MLinkMuxIf* DMultiplexer::RegisterLink(
        MMuxLinkIf* aLink,
        const TUint8 aTrxId,
        const TUint8 aLinkId
        )
    {

    C_TRACE( ( _T( "DMultiplexer::RegisterLink 0x%x id %d %d>" ), aLink, aLinkId, aTrxId ) );
    ASSERT_RESET_ALWAYS( ( aLink ), ( EMultiplexerNullParam | EDMultiplexerTraceId << KClassIdentifierShift ) );
    ASSERT_RESET_ALWAYS( ( EAmountOfTrxs > aTrxId ), ( EMultiplexerInvalidTrxId | EDMultiplexerTraceId << KClassIdentifierShift ) );
    DMux* mux = GetMuxForTrx( aTrxId );
    mux->SetLink( aLink, aLinkId );
    C_TRACE( ( _T( "DMultiplexer::RegisterLink 0x%x id %d %d mux 0x%x<" ), aLink, aLinkId, aTrxId, mux ) );
    return mux;

    }

/*
* Creates new multiplexer for transceiver if not existing, if exists selects the existing one.
* Returns a pointer to transceivers multiplexer.
*/
DMux* DMultiplexer::GetMuxForTrx(
        const TUint8 aTrxId
        )
    {

    C_TRACE( ( _T( "DMultiplexer::GetMuxForTrx id %d>" ), aTrxId ) );
    TInt err( Kern::MutexWait( *iShMultiplexersMutex ) );
    ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EMultiplexerMutexWaitFailed| EDMultiplexerTraceId << KClassIdentifierShift ) );
    DMux* mux = iShMultiplexers[ aTrxId ];
    if( !mux )
        {
        DMux* newMux = new DMux( aTrxId );
        iShMultiplexers[ aTrxId ] = newMux;
        mux = newMux;
        }
    ASSERT_RESET_ALWAYS( ( mux ), EMultiplexerMemAllocFailure );
    Kern::MutexSignal( *iShMultiplexersMutex );
    C_TRACE( ( _T( "DMultiplexer::GetMuxForTrx mux 0x%x id %d<" ), mux, aTrxId ) );
    return mux;

    }

DECLARE_STANDARD_EXTENSION()
    {

    Kern::Printf( "Multiplexer (L2) extension>" );
    // Create a container extension
    DMultiplexer* extension = new DMultiplexer();
    ASSERT_RESET_ALWAYS( ( extension ), ( EMultiplexerMemAllocFailure2 | EDMultiplexerTraceId << KClassIdentifierShift ) );
    Kern::Printf( "Multiplexer (L2) extension<" );
    return extension ? KErrNone : KErrNoMemory;

    }