void DISIKernelChannel::DoCancel(
    TInt aRequest,
    TInt aMask )
{
    C_TRACE( ( _T( "DISIKernelChannel::DoCancel 0x%x 0x%x>" ), this, iObjId ) );
    ASSERT_RESET_ALWAYS( EISILastAsyncRequest > ( aMask&aRequest ), EISIKernelChannelOverTheLimits | EDISIKernelChannelId << KClassIdentifierShift );
    if( iRequests->IsPending( aMask&aRequest ) )
    {
        switch( aMask&aRequest )
        {
        case EISIAsyncReceive:
        {
            C_TRACE( ( _T( "DISIKernelChannel::DoCancel EIADAsyncReceive 0x%x ptrs 0x%x 0x%x" ), this, iPtrPtrToRxBuf, &iPtrPtrToRxBuf ) );
            iPtrPtrToRxBuf = NULL;
            break;
        }
        default:
        {
            ASSERT_RESET_ALWAYS( 0, EISIKernelChannelWrongRequest | EDISIKernelChannelId << KClassIdentifierShift );
            break;
        }
        }
        EnqueChannelRequestCompleteDfc( aMask&aRequest, KErrCancel );
    }
    else
    {
        C_TRACE( ( _T( "DISIKernelChannel::DoCancel nothing to cancel 0x%x" ), this ) );
    }
    C_TRACE( ( _T( "DISIKernelChannel::DoCancel 0x%x 0x%x<" ), this, iObjId ) );
}
TInt DISICLTransceiver::SendCommIsaEntityNotReachableResp(
        TDes8& aNotDeliveredMessage
        )
    {
    C_TRACE( ( _T( "DISICLTransceiver::SendCommIsaEntityNotReachableResp 0x%x>" ), &aNotDeliveredMessage ) );
    const TUint8* notDeliveredMsgPtr( aNotDeliveredMessage.Ptr() );
    TInt error = KErrAlreadyExists;
    // Avoid COMM_ISA_ENTITY_NOT_REACHABLE_RESP loop.
    if( ( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_MESSAGEID ] == COMMON_MESSAGE ) &&
        ( ( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_SUBMESSAGEID ] == COMM_ISA_ENTITY_NOT_REACHABLE_RESP ) || 
          ( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_SUBMESSAGEID ] == COMM_SERVICE_NOT_IDENTIFIED_RESP ) ) )
        {
        C_TRACE( ( _T( "DISICLTransceiver Not sending another CommIsaEntityNotReachableResp 0x%x 0x%x" ), &aNotDeliveredMessage, notDeliveredMsgPtr[ ISI_HEADER_OFFSET_SUBMESSAGEID ] ) );
        }
    else
        {
        // Follows COMM specification: 000.031
        TUint8 length( ISI_HEADER_SIZE + SIZE_COMMON_MESSAGE_COMM_ISA_ENTITY_NOT_REACHABLE_RESP );
        TDes8& respMsg = MemApi::AllocBlock( length );
        ASSERT_RESET_ALWAYS( length > ISI_HEADER_OFFSET_MESSAGEID, ( EISICLTransceiverOverTheLimits | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
        TUint8* respMsgPtr = const_cast<TUint8*>( respMsg.Ptr() );
        // We start to append from transaction id.
        respMsg.SetLength( ISI_HEADER_OFFSET_TRANSID );
        // Get the header until messageid from prev. message.
        // Just turn receiver and sender device and object vice versa.
        respMsgPtr[ ISI_HEADER_OFFSET_MEDIA ] = notDeliveredMsgPtr[ ISI_HEADER_OFFSET_MEDIA ];
        SET_RECEIVER_DEV( respMsgPtr, GET_SENDER_DEV( aNotDeliveredMessage ) );
        SET_SENDER_DEV  ( respMsgPtr, GET_RECEIVER_DEV( aNotDeliveredMessage ) );
        respMsgPtr[ ISI_HEADER_OFFSET_RESOURCEID ] = notDeliveredMsgPtr[ ISI_HEADER_OFFSET_RESOURCEID ];
        SET_LENGTH( respMsgPtr, ( length - PN_HEADER_SIZE ) );
        SET_RECEIVER_OBJ( respMsgPtr, GET_SENDER_OBJ( aNotDeliveredMessage ) );
        SET_SENDER_OBJ( respMsgPtr, GET_RECEIVER_OBJ( aNotDeliveredMessage ) );
        // Set from undelivered message
        respMsg.Append( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_TRANSID ] );
        // Message Identifier
        respMsg.Append( COMMON_MESSAGE );
        // Sub message Identifier.
        respMsg.Append( COMM_ISA_ENTITY_NOT_REACHABLE_RESP );
        // Not Delivered Message from original message.
        respMsg.Append( notDeliveredMsgPtr[ ISI_HEADER_OFFSET_MESSAGEID ] );
        // Status
        respMsg.Append( COMM_ISA_ENTITY_NOT_AVAILABLE );//  different status in a case of device not existing
        // Filler
        const TUint8 KFiller( 0x00 );
        respMsg.Append( KFiller );
        // Filler
        respMsg.Append( KFiller );
        // Filler
        respMsg.Append( KFiller );
        error = RouteISIMessage( respMsg, EFalse );
        // Programming error in this function if below assert is raised
        ASSERT_RESET_ALWAYS( KErrNone == error, ( EISICLTransceiverCommIsaEntityNotReachableResp | EDISICLTransceiverTraceId << KClassIdentifierShift ) );        
        }
    MemApi::DeallocBlock( aNotDeliveredMessage );
    C_TRACE( ( _T( "DISICLTransceiver::SendCommIsaEntityNotReachableResp 0x%x<" ), &aNotDeliveredMessage ) );
    return error;

    }
DISICLTransceiver::DISICLTransceiver(
        DISIRouter& aRouter,
        TDfcQue* aThreadPtr
        )
    : iShRouter( aRouter )
    {
    C_TRACE( ( _T( "DISICLTransceiver::DISICLTransceiver>" ) ) );
    ASSERT_RESET_ALWAYS( aThreadPtr, ( EISICLTransceiverNULLPtr7 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    iShStateChangedDfc = new TDfc( StateChangedDfc, this, aThreadPtr, KDfcPriority );
    ASSERT_RESET_ALWAYS( iShStateChangedDfc, ( EISICLTransceiverMemAllocFailure6 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    
    iRxQueueDfc = new TDfc( RxQueueDfc, this, aThreadPtr, KDfcPriority );
    ASSERT_RESET_ALWAYS( iShStateChangedDfc, ( EISICLTransceiverMemAllocFailure8 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
            
    DISIDevice* dev = new DISIDevice( PN_DEV_MODEM,
                                      MISIRouterLinkIf::CreateLinkF( this, PN_MEDIA_MODEM_HOST_IF, ETrxSharedMemory)
                                      );
    ASSERT_RESET_ALWAYS( dev, ( EISICLTransceiverMemAllocFailure3 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    iShDevices.Append( dev );
#ifdef USE_MEDIAAPI 
    DISIDevice* dev2 = new DISIDevice( PN_DEV_PC,  // append to dynamic table if needed
                                       MISIRouterLinkIf::CreateLinkF( this, PN_MEDIA_USB, ETrxUSB )
                                      );
    ASSERT_RESET_ALWAYS( dev2, ( EISICLTransceiverMemAllocFailure9 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    iShDevices.Append( dev2 );
    
    DISIDevice* dev4 = new DISIDevice( PN_DEV_PC,  // append to dynamic table if needed
                                       MISIRouterLinkIf::CreateLinkF( this, PN_MEDIA_BT, ETrxBT )
                                      );
    ASSERT_RESET_ALWAYS( dev4, ( EISICLTransceiverMemAllocFailure10 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    iShDevices.Append( dev4 );
 #endif /* USE_MEDIAAPI */
	  DISIDevice* dev3 = new DISIDevice( PN_DEV_DUMMYIST,
                                       MISIRouterLinkIf::CreateLinkF( this, PN_MEDIA_TEST, ETrxTest )
                                      );                                      
    ASSERT_RESET_ALWAYS( dev3, ( EISICLTransceiverMemAllocFailure5 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    iShDevices.Append( dev3 );

    iRouterService = new DIsiRouterService( *this );
    ASSERT_RESET_ALWAYS( iRouterService, ( EISICLTransceiverMemAllocFailure2 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    
    iRxQueue = new DISIMsgQueue( KISIMainRxQueueSize );
    ASSERT_RESET_ALWAYS( iRxQueue, ( EISICLTransceiverMemAllocFailure7 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    
    TInt err( Kern::MutexCreate( iDynamicDeviceTableMutex, KISICLTransceiverMutex, KMutexOrdGeneral0 ) );
    ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EISICLTransceiverMutexCreateFailed | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
#ifdef USE_MEDIAAPI 
    iDevPcLastSendTrxId = EAmountOfTrxs;  //put a maxvalue	
    iDevPcLastActiveTrxId = EAmountOfTrxs;  //put a maxvalue
#endif /* USE_MEDIAAPI */
    C_TRACE( ( _T( "DISICLTransceiver::DISICLTransceiver<" ) ) );
    }
void DISIRouter::Initialize(
        // None
        )
    {
    C_TRACE( ( _T( "DISIRouter::Initialize> this: 0x%x" ), this ) );
    iSelfPtr = this;
    iClientTableFastMutex = new NFastMutex();
    ASSERT_RESET_ALWAYS( iClientTableFastMutex, ( EISIRouterNULLPtr2 | EDISIRouterTraceId << KClassIdentifierShift ) );
    for( TInt i( 0 ); i < KMaxAmountOfObjId; i++)
        {
        iClientTable[ i ] = NULL;
        }
    //  comment improve hex or des
    //  nameservice, communication manager, routerservice...
    //                                       UID  ObjId
    iStaticObjIdTable.Append( new TStaticId( 123, 0x70 ) ); //  for testing ISI API
    iStaticObjIdTable.Append( new TStaticId( 200, 0x71 ) ); //  for testing ISI API
    iStaticObjIdTable.Append( new TStaticId( 201, 0x72 ) ); //  for testing ISI API
    iStaticObjIdTable.Append( new TStaticId( 202, 0x73 ) ); //  for testing ISI API
    //
#ifndef WITHOUT_WRAPPERS_IN_USE
    // Map all the kernel channels as they used to be
    for( TInt id( KFirstUserChannel ); id < KLastKernelChannel; id++ )
        {
        if ( ( id != KNotInitializedId ) &&
             ( id != PN_OBJ_EVENT_MULTICAST ) &&
             ( id != PN_OBJ_EVENT_MULTICAST ) &&
             ( id != ROUTER_OBJECT_IDENTIFIER ) &&
             ( id != PIPEHANDLER_OBJECT_IDENTIFIER ) ) 
            {        
            iStaticObjIdTable.Append( new TStaticId( id, id ) );
            }
        else
            {
            iStaticObjIdTable.Append( new TStaticId( id, 0xEE ) );
            }
        }
    // Map all the kernel channels as they used to be
#endif // WITHOUT_WRAPPERS_IN_USE
    // ? vaikutus iShClientThreadContainer->DeallocateThread( iInitThread );

    iStaticObjIdTable.Append( new TStaticId( 0xD11BADA1, KNotInitializedId ) );// Make sure no one can get KNotInitializedId obj id
    iStaticObjIdTable.Append( new TStaticId( KCommunicationManagerUID, PN_OBJ_EVENT_MULTICAST ) );
    iStaticObjIdTable.Append( new TStaticId( KNameServiceUID, PN_OBJ_ROUTING_REQ ) );
    iStaticObjIdTable.Append( new TStaticId( KIsiShRouterServiceUID, ROUTER_OBJECT_IDENTIFIER ) );
    iStaticObjIdTable.Append( new TStaticId( KIsiShPipeHandlerUID, PIPEHANDLER_OBJECT_IDENTIFIER ) );
    
    iShCLTransceiver = new DISICLTransceiver( *this, iInitThread );
    ASSERT_RESET_ALWAYS( iShCLTransceiver, ( EISIRouterNULLPtr1 | EDISIRouterTraceId << KClassIdentifierShift ) ); 
    
    C_TRACE( ( _T( "DISIRouter::Initialize<" ) ) );
    }
DISIRouter::DISIRouter(
        // None
        )
    {
    C_TRACE( ( _T( "DISIRouter::DISIRouter>" ) ) );
    iShClientThreadContainer = new DISIThreadContainer();
    ASSERT_RESET_ALWAYS( iShClientThreadContainer, ( EISIRouterMemAllocFailure1 | EDISIRouterTraceId << KClassIdentifierShift ) );
    iInitThread = iShClientThreadContainer->AllocateThread( MISIObjectRouterIf::EISIKernelMainThread );
    ASSERT_RESET_ALWAYS( iInitThread, ( EISIRouterNULLThreadPointer | EDISIRouterTraceId << KClassIdentifierShift ) );
    iInitializeDfc = new TDfc( InitializeDfc, this, iInitThread, KDfcPriority );
    ASSERT_RESET_ALWAYS( iInitializeDfc, ( EISIRouterMemAllocFailure2 | EDISIRouterTraceId << KClassIdentifierShift ) );
    iInitializeDfc->Enque();
    C_TRACE( ( _T( "DISIRouter::DISIRouter<" ) ) );
    }
DISICLTransceiver::DISIDevice::DISIDevice(
        const TUint8 aDeviceIdentifier,
        MISIRouterLinkIf* aLink
        )
    {
    C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::DISIDevice 0x%x 0x%x 0x%x>" ), aDeviceIdentifier, aLink ) );
    iShDeviceIdentifier = aDeviceIdentifier;
    iShOldDeviceConnectedState = EFalse;
    ASSERT_RESET_ALWAYS( aLink, ( EISICLTransceiverNULLPtr2 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    iShLink = aLink;
    iShDeviceMutex = new NFastMutex();
    ASSERT_RESET_ALWAYS( iShDeviceMutex, EISICLTransceiverNULLPtr6 | EDISICLTransceiverTraceId << KClassIdentifierShift );
    C_TRACE( ( _T( "DISICLTransceiver::DISIDevice::DISIDevice<" ) ) );
    }
void DISICLTransceiver::UpdateDynamicDeviceTable( const TUint8 aDynamicDevId, const TUint8 aStaticDevId )
    {
    C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable 0x%x 0x%x>" ), aDynamicDevId, aStaticDevId) );
    TBool deviceExist(EFalse);
    TInt count(iDynamicDeviceTable.Count());
    TInt err( Kern::MutexWait( *iDynamicDeviceTableMutex ) );
    ASSERT_RESET_ALWAYS( ( err == KErrNone ), ( EISICLTransceiverMutexWaitFailed2 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    for( TUint8 i = 0; i < count; i++ )
        {
        C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable find dynamic device %d" ), i) );
        if( iDynamicDeviceTable[ i ]->iDynamicDevId == aDynamicDevId )
            {                    
            C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable dyn dev exist i = %d aDynamicDevId 0x%x staticDevId 0x%x previous 0x%x" ), i, iDynamicDeviceTable[ i ]->iDynamicDevId, aStaticDevId, iDynamicDeviceTable[ i ]->iStaticDevId ) );
            iDynamicDeviceTable[ i ]->iStaticDevId = aStaticDevId;
            deviceExist = ETrue;
            break;
            }
        }
        
    if ( !deviceExist )
        {
        C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable new dynamic device added 0x%x 0x%x" ), aDynamicDevId, aStaticDevId ) );
        iDynamicDeviceTable.Append( new TDynamicDevice( aDynamicDevId, aStaticDevId ) );
        }
    Kern::MutexSignal( *iDynamicDeviceTableMutex );
    C_TRACE( ( _T( "DISICLTransceiver::UpdateDynamicDeviceTable 0x%x 0x%x<" ), aDynamicDevId, aStaticDevId) );
    }
void DISICLTransceiver::GetDeviceConnectionStates(
        RArray<TUint8>& aDeviceIdentifierList,
        const TBool aConnectedDevice
        )
    {
    C_TRACE( ( _T( "DISICLTransceiver::GetDeviceConnectionStates 0x%x 0x%x>" ), &aDeviceIdentifierList, aConnectedDevice ) );

    const TInt count( iShDevices.Count() );
    for( TInt index( 0 ); index < count; index++ )
        {
        DISIDevice* tmpDevice = iShDevices[ index ];
        ASSERT_RESET_ALWAYS( tmpDevice, ( EISICLTransceiverNULLPtr3 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
        tmpDevice->LockDeviceFM();
        if( tmpDevice->GetDeviceState() == aConnectedDevice )
            {
            const TUint8 deviceIdentifier( tmpDevice->GetDeviceIdentifier() );
            tmpDevice->FreeDeviceFM();
            aDeviceIdentifierList.Append( deviceIdentifier );
            }
        else
            {
            tmpDevice->FreeDeviceFM();
            }
        }
    C_TRACE( ( _T( "DISICLTransceiver::GetDeviceConnectionStates 0x%x 0x%x<" ), &aDeviceIdentifierList, aConnectedDevice ) );
    }
// -----------------------------------------------------------------------------
// E32Dll
// Epoc Kernel Architecture 2 style entry point
// ( other items were commented in a header ).
// -----------------------------------------------------------------------------
//
DECLARE_STANDARD_LDD()
    {
    DLogicalDevice* device = new DIscDevice;
    if ( !device )
        {
        ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscPanicCreateLogicalDevice );
        }
    return device;
    }
void DISIKernelChannel::DISIKernelAsyncRequests::SetPending(
    const TUint aRequest,
    TDfc* aDfc,
    TRequestStatus* aStatus
)
{
    C_TRACE( ( _T( "DISIKernelAsyncRequests::SetPending %d 0x%x 0x%x>" ), aRequest, aDfc, aStatus ) );
    ASSERT_RESET_ALWAYS( aDfc, ( EISIKernelChannelNullParam5 | EDISIKernelChannelId << KClassIdentifierShift ) );
    ASSERT_RESET_ALWAYS( aStatus, ( EISIKernelChannelNullParam6 | EDISIKernelChannelId << KClassIdentifierShift ) );
    ASSERT_RESET_ALWAYS( ( EISILastAsyncRequest > aRequest && EISIAsyncReceive <= aRequest ), ( EISIKernelChannelOverTheLimits2 | EDISIKernelChannelId << KClassIdentifierShift ) );
    // Note asserts must be done before holding the lock.
    NKern::FMWait( iRequestLock );
    iDfcFunctionList[ aRequest ] = aDfc;
    iRequestStatusList[ aRequest ] = aStatus;
    *iRequestStatusList[ aRequest ] = KRequestPending;
    NKern::FMSignal( iRequestLock );
    C_TRACE( ( _T( "DISIKernelAsyncRequests::SetPending %d 0x%x 0x%x<" ), aRequest, aDfc, aStatus ) );
}
TInt DISIKernelChannel::HandleRequest(
    TThreadMessage& aMsg
)
{
    C_TRACE( ( _T( "DISIKernelChannel::HandleRequest 0x%x 0x%x 0x%x>" ), this, aMsg.iValue, iObjId ) );
    __ASSERT_CRITICAL;
    __ASSERT_NO_FAST_MUTEX;
    ASSERT_THREAD_CONTEXT_ALWAYS( ( EISIKernelChannelNotThreadContext | EDISIKernelChannelId << KClassIdentifierShift ) );
    TInt valueToReturn( KErrAlreadyExists );
    // Channel is not open.
    if( iObjId == KNotInitializedId )
    {
        switch( aMsg.iValue )
        {
        // Only connect is legal
        case EISIConnect:
        {
            C_TRACE( ( _T( "DISIKernelChannel::HandleRequest connect 0x%x" ), this ) );
            valueToReturn = aMsg.SendReceive( &iKernelChMsgQue );
            break;
        }
        default:
        {
            ASSERT_RESET_ALWAYS( 0, ( EISIKernelChannelWrongParam | EDISIKernelChannelId << KClassIdentifierShift ) );
            break;
        }
        }
    }
    // Channel is open.
    else
    {
        // Accept all calls except new.
        if( EISIConnect != aMsg.iValue )
        {
            valueToReturn = aMsg.SendReceive( &iKernelChMsgQue );
        }
        else
        {
            ASSERT_RESET_ALWAYS( ( 0 ), ( EISIKernelChannelAlreadyCreated | EDISIKernelChannelId << KClassIdentifierShift ) );
        }
    }
    C_TRACE( ( _T( "DISIKernelChannel::HandleRequest 0x%x %d 0x%x<" ), this, valueToReturn, iObjId ) );
    return valueToReturn;
}
DISIKernelChannel::DISIKernelChannel(
    const TUint16& aObjId
) : iKernelChMsgQue( MsgQDfc, this, NULL, KISIKernelChannelMsgQueDfcPrio )
    , iObjId(KNotInitializedId)
    , iUID( KNotInitializedUID )
{
    C_TRACE( ( _T( "DISIKernelChannel::DISIKernelChannel 0x%x>" ), this ) );
    iRouterIf = MISIObjectRouterIf::GetIf();
    ASSERT_RESET_ALWAYS( iRouterIf, ( EISIKernelChannelMemAllocFailure | EDISIKernelChannelId << KClassIdentifierShift ) );
    iRequests = new DISIKernelAsyncRequests( EISILastAsyncRequest );
    iRx = new DISIMsgQueue( KISILddRxQueueSize );
    iCompletionThread = iRouterIf->GetDfcThread( MISIObjectRouterIf::EISIUserRequestCompletionThread );
    iEmptyRxDfc = new TDfc( EmptyRxDfc, this, iCompletionThread, KISIKernelEmptyRxQueuePrio );
    ASSERT_RESET_ALWAYS( ( iEmptyRxDfc && iRequests && iRx ), ( EISIKernelChannelMemAllocFailure1 | EDISIKernelChannelId << KClassIdentifierShift ) );
    iMainThread = iRouterIf->GetDfcThread( MISIObjectRouterIf::EISIKernelMainThread );
    iKernelChMsgQue.SetDfcQ( iMainThread );
    iKernelChMsgQue.Receive();
    C_TRACE( ( _T( "DISIKernelChannel::DISIKernelChannel 0x%x<" ), this ) );
}
void DISICLTransceiver::StateChangedDfc(
        TAny* aPtr
        )
    {
    C_TRACE( ( _T( "DISICLTransceiver::StateChangedDfc>" ) ) );
    DISICLTransceiver* self = reinterpret_cast<DISICLTransceiver*>( aPtr );
    ASSERT_RESET_ALWAYS( self, ( EISICLTransceiverNULLPtr5 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    self->ReadStateChanges();
    C_TRACE( ( _T( "DISICLTransceiver::StateChangedDfc<" ) ) );
    }
// -----------------------------------------------------------------------------
// DIscDevice::InitializeLdd2LddInterface
// Function to connect to DataTransmission and Multiplexer ldds
// ( other items were commented in a header ).
// -----------------------------------------------------------------------------
//
TInt DIscDevice::InitializeLdd2LddInterface()
    {
    C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface()" ) ) );
    
    // Find pointer to second level LDD.
    DObjectCon* lDevices = Kern::Containers()[ ELogicalDevice ];
    TKName driverName;
    ASSERT_RESET_ALWAYS( lDevices, "IscDriver", EIscLogicalDevicesNotFound );

    TInt err( KErrNone );
    //TInt driverHandle( KErrNone ); // API change in SOS9.2 WK08
	TFindHandle driverHandle;
    // Find pointer to ISC Multiplexer.
    err = lDevices->FindByName( driverHandle, KIscMultiplexerName, driverName );
    if( KErrNone != err )
        {
        C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface() ISC Multiplexer Not Found!" ) ) );
        ASSERT_RESET_ALWAYS( 0, "IscDriver" ,EIscMultiplexerNotFound );
        }
	
    iIscMultiplexerInterface = static_cast<DIscMultiplexerBase*>( lDevices->At( driverHandle ) );
    ASSERT_RESET_ALWAYS( iIscMultiplexerInterface, "IscDriver", EIscMultiplexerNotFound );

    //TInt secondDriverHandle( KErrNone );  // API change in SOS9.2 WK08
	TFindHandle secondDriverHandle;
    // Find pointer to Data Transmission Plugin.
    err = lDevices->FindByName( secondDriverHandle, KIscDataTransmissionDriverName, driverName );
    if( KErrNone != err )
        {
        C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface() Data Transmission Plug-In Not Found!" ) ) );
        ASSERT_RESET_ALWAYS( 0, "IscDriver", EIscDataTransmissionDriverNotFound );
        }

    iIscDataTransmissionInterface = static_cast<DIscDataTransmissionBase*>( lDevices->At( secondDriverHandle ) );
    ASSERT_RESET_ALWAYS( iIscDataTransmissionInterface, "IscDriver", EIscDataTransmissionDriverNotFound );
    
    iIscDataTransmissionInterface->Connect( this );
    iIscMultiplexerInterface->Connect( this );

    C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface - return 0x%x" ), err ) );
    return err;
    
    }
void DISIRouter::Connect(
        const TInt32 aUID,
        TUint8& aObjId, 
        MISIRouterObjectIf* aCallback
        )
    {
    C_TRACE( ( _T( "DISIRouter::Connect 0x%x 0x%x 0x%x 0x%x>" ), aUID, aObjId, aCallback, this ) );
    ASSERT_RESET_ALWAYS( aCallback, ( EISIRouterNULLPtr | EDISIRouterTraceId << KClassIdentifierShift ) );
    TISIClient* tmp = new TISIClient();
    ASSERT_RESET_ALWAYS( tmp, ( EISIRouterMemAllocFailure | EDISIRouterTraceId << KClassIdentifierShift ) );
    tmp->iUID = aUID;
    tmp->iChannel = aCallback;
    TUint8 staticObjId = ReserveStaticObjId( aUID );
    NKern::FMWait( iClientTableFastMutex );
    TBool reserved = CheckUIDUniqueness( aUID );
#ifndef WITHOUT_WRAPPERS_IN_USE
    if( reserved )
        {
        NKern::FMSignal( iClientTableFastMutex );
        aObjId = 0xEE;
        }
    else
        {
#endif //WITHOUT_WRAPPERS_IN_USE
        if( KNotInitializedId == staticObjId )
            {
            tmp->iObjId = ReserveNewDynamicObjId();
            ASSERT_RESET_ALWAYS( tmp->iObjId, ( EISIRouterNULLObjId | EDISIRouterTraceId << KClassIdentifierShift ) );
            }
        else
            {
            tmp->iObjId = staticObjId;//  check that dynamic allocation don't return statically reserved object identifiers
            }
        iClientTable[ tmp->iObjId ] = tmp;
        NKern::FMSignal( iClientTableFastMutex );
        aObjId = tmp->iObjId;
#ifndef WITHOUT_WRAPPERS_IN_USE
        }
#endif
    C_TRACE( ( _T( "DISIRouter::Connect 0x%x 0x%x 0x%x<" ), aUID, aObjId, aCallback ) );
    }
void DISIKernelChannel::DISIKernelAsyncRequests::Complete(
    const TUint aRequest,
    const TInt aStatusToComplete
)
{
    C_TRACE( ( _T( "DISIKernelAsyncRequests::Complete %d>" ), aRequest ) );
    // Check that request is legal.
    ASSERT_RESET_ALWAYS( ( EISILastAsyncRequest > aRequest && EISIAsyncReceive <= aRequest ), ( EISIKernelChannelOverTheLimits4 | EDISIKernelChannelId << KClassIdentifierShift ) );
    NKern::FMWait( iRequestLock );
    TDfc* completeDfc = iDfcFunctionList[ aRequest ];
    if( ( completeDfc && iRequestStatusList[ aRequest ] ) )
    {
        // Writing straight to clients pointer. There is a risk that malfunctioning client can mess up it's own pointer, if used out side of rx dfc, but what can you do..
        *iRequestStatusList[ aRequest ] = aStatusToComplete;
        ASSERT_RESET_ALWAYS( !completeDfc->Queued(), ( EISIKernelChannelDfcAlreadyQueued | EDISIKernelChannelId << KClassIdentifierShift ) );
        completeDfc->Enque();
        iDfcFunctionList[ aRequest ] = NULL;
    }
    NKern::FMSignal( iRequestLock );
    C_TRACE( ( _T( "DISIKernelAsyncRequests::Complete %d<" ), aRequest ) );
}
EXPORT_C TDfcQue* DIsaAccessExtension::GetDFCThread
        (
        TIADDfcThread aDfcThread
        )
    {

    C_TRACE( ( _T( "DIsaAccessExtension::GetDFCThread <->" ) ) );
    ASSERT_RESET_ALWAYS( ( EIADLddDfcQueue == aDfcThread || EIADExtensionDfcQueue == aDfcThread ), EIADDFCThreadGetFailed | EIADFaultIdentifier2 << KFaultIdentifierShift );
    // Ownership not given to caller.
    return iDfcQueueList[ EIADExtensionDfcQueue ];//SMPSAFE

    }
// This is called in 1...N thread contextes
void DISICLTransceiver::ReceiveISIMessage(
        const TDesC8& aMessage,
        const TUint8 aTrxId
        )
    {
    C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg 0x%x 0x%x 0x%x>" ), this, &aMessage, aTrxId ) );
    // Can only be called from thread context.
    ASSERT_THREAD_CONTEXT_ALWAYS( ( EISICLTransceiverNotThreadContext | EDISIUserChannelTraceId << KClassIdentifierShift ) );
    
    TUint8 txDevId = GET_SENDER_DEV( aMessage.Ptr() );    
    if ( DynamicDevice( txDevId ) )
        {
        TUint8 staticDevId(0);
        const TInt count( iShDevices.Count() );        
        TInt index(0);
        TBool staticDeviceFound(EFalse);
        MISIRouterLinkIf* Link = NULL;
        while( !staticDeviceFound && ( index < count ) )
            {
            C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg find static device for trx 0x%x index %d" ), aTrxId, index ) );
            DISIDevice* tmpDevice = iShDevices[ index ];
            ASSERT_RESET_ALWAYS( tmpDevice, ( EISICLTransceiverNULLPtr4 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
            tmpDevice->LockDeviceFM();
            Link = tmpDevice->GetLink();
            if( Link->GetTrxId() == aTrxId )
                {                
                staticDevId = tmpDevice->GetDeviceIdentifier();
                tmpDevice->FreeDeviceFM();
                C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg static device 0x%x trx 0x%x" ), this, &aMessage, aTrxId ) );
                staticDeviceFound = ETrue;
                }
            else
                {
                tmpDevice->FreeDeviceFM();
                }
            index++;
            } 
#ifdef USE_MEDIAAPI 		 
        if ( PN_DEV_PC == GET_SENDER_DEV( aMessage.Ptr() ))
            {
            C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg 0x%x 0x%x trx id = %d<" ), this, &aMessage, (Link->GetTrxId())  ) ); 
            iDevPcLastActiveTrxId = iDevPcLastSendTrxId;                  	
            iDevPcLastSendTrxId =	Link->GetTrxId();                       	    
            }		     
#endif /* USE_MEDIAAPI */  			
        UpdateDynamicDeviceTable( txDevId, staticDevId );
        }
    // else static device. No need to save trxId

    iRxQueue->Add( aMessage );
    iRxQueueDfc->Enque();
    C_TRACE( ( _T( "DISICLTransceiver::ReceiveMsg 0x%x 0x%x 0x%x<" ), this, &aMessage, aTrxId ) );
    }
TBool DISIKernelChannel::DISIKernelAsyncRequests::IsPending(
    const TUint aRequest
)
{
    C_TRACE( ( _T( "DISIKernelAsyncRequests::IsPending %d>" ), aRequest ) );
    ASSERT_RESET_ALWAYS( ( EISILastAsyncRequest > aRequest && EISIAsyncReceive <= aRequest ), ( EISIKernelChannelOverTheLimits3 | EDISIKernelChannelId << KClassIdentifierShift ) );
    TBool ret( EFalse );
    NKern::FMWait( iRequestLock );
    ret = ( iDfcFunctionList[ aRequest ] && iRequestStatusList[ aRequest ] ) ? ETrue : EFalse;
    NKern::FMSignal( iRequestLock );
    C_TRACE( ( _T( "DISIKernelAsyncRequests::IsPending %d %d<" ), aRequest, ret ) );
    return ret;
}
void DISIKernelChannel::HandleThreadMsg(
    TThreadMessage& aMsg
)
{
    C_TRACE( ( _T( "DISIKernelChannel::HandleThreadMsg 0x%x 0x%x 0x%x>" ), this, &aMsg, iObjId ) );
    TThreadMessage& m = ( aMsg );
    TInt completeValue( KErrNone );
    TBool complete( ETrue );
    switch( m.iValue )
    {
    // All asynchronous requests. Return result after DFC function is run.
    case EISIAsyncReceive:
    {
        // No need to check return value in async functions, completed to client from DFC.
        HandleDfcRequest( m );
        break;
    }
    // From synchronized request return the result immediately
    case EISIConnect:
    case EISIDisconnect:
    case EISIAllocateBlock:
    case EISIDeallocateBlock:
    case EISISend:
    {
        completeValue = HandleSyncRequest( m );
        break;
    }
    case KDestroyChannelMsg:
    {
        completeValue = KErrNone;
        // Don't receive anymore messages.
        complete = EFalse;
        break;
    }
    case KMaxTInt:
    {
        completeValue = KErrNone;
        DoCancel( KMaxTInt, m.Int0() );
        break;
    }
    default:
    {
        ASSERT_RESET_ALWAYS( 0, ( EISIKernelChannelWrongRequest | EDISIKernelChannelId << KClassIdentifierShift ) );
        break;
    }
    }
    m.Complete( completeValue, complete );
    C_TRACE( ( _T( "DISIKernelChannel::HandleThreadMsg 0x%x< 0x%x" ), this, iObjId ) );
}
DIsaAccessExtension::DIsaAccessExtension
        (
        // None
        )
    {

    C_TRACE( ( _T( "DIsaAccessExtension::DIsaAccessExtension ->" ) ) );
    // One above DFCQue0 (27)
    TInt defaultDfcPriority( 27 ); //TODO: NOTE!!! change to use DFCQue0 priority if possible //Kern::DfcQue0()->iThread->iPriority; NOTE!! IST prios
    // LDD DFC queue.
    TDfcQue* lddTDfcQueue = NULL;
    ASSERT_RESET_ALWAYS( KErrNone == Kern::DfcQCreate( lddTDfcQueue, defaultDfcPriority + KIADLddPrioriAdd, &KIADLddDfc ), EIADDFCThreadCreationFailed );
    iDfcQueueList[ EIADLddDfcQueue ] = lddTDfcQueue; 
    // Extension DFC queue.
    TDfcQue* extensionTDfcQueue = NULL;
    ASSERT_RESET_ALWAYS( KErrNone == Kern::DfcQCreate( extensionTDfcQueue, defaultDfcPriority + KIADExtensionPrioriAdd, &KIADExtensionDfc ), EIADDFCThreadCreationFailed );
    iDfcQueueList[ EIADExtensionDfcQueue ] = extensionTDfcQueue; 
    C_TRACE( ( _T( "DIsaAccessExtension::DIsaAccessExtension <-" ) ) );
    iRouter = new DRouter();
    ASSERT_RESET_ALWAYS( iRouter, EIADMemoryAllocationFailure | EIADFaultIdentifier4 << KFaultIdentifierShift );
//    _LIT8( KIADCOMPONAME, "ISA ACCESS DRIVER" );
    //BUILD_TRACE( KIADCOMPONAME() );

    }
void DISICLTransceiver::DynamicToStaticDevice( TUint8& aRxDev )
    {
    C_TRACE( ( _T( "DISICLTransceiver::DynamicToStaticDevice aRxDev>" ), &aRxDev ) );
    TInt err( Kern::MutexWait( *iDynamicDeviceTableMutex ) );
    ASSERT_RESET_ALWAYS( ( err == KErrNone ), ( EISICLTransceiverMutexWaitFailed | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
    for( TUint8 i = 0; i < iDynamicDeviceTable.Count(); i++ )
        {
        if( iDynamicDeviceTable[ i ]->iDynamicDevId == aRxDev )
            {                    
            C_TRACE( ( _T( "DISICLTransceiver::DynamicToStaticDevice dyn dev exist i = %d iDynamicDevId 0x%x iStaticDevId 0x%x" ), i, iDynamicDeviceTable[ i ]->iDynamicDevId, iDynamicDeviceTable[ i ]->iStaticDevId) );
            aRxDev = iDynamicDeviceTable[ i ]->iStaticDevId;
            break;
            }
        }
    Kern::MutexSignal( *iDynamicDeviceTableMutex );
    C_TRACE( ( _T( "DISICLTransceiver::DynamicToStaticDevice aRxDev<" ), &aRxDev ) );
    }
void DISICLTransceiver::ReadStateChanges(
        // None
        )
    {

    C_TRACE( ( _T( "DISICLTransceiver::ReadStateChanges>" ) ) );

    const TInt count( iShDevices.Count() );
    for( TInt index( 0 ); index < count; index++ )
        {
        DISIDevice* tmpDevice = iShDevices[ index ];
        ASSERT_RESET_ALWAYS( tmpDevice, ( EISICLTransceiverNULLPtr6 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
        tmpDevice->LockDeviceFM();
        const TBool connected = tmpDevice->GetDeviceState();//  tee paremmaksi
	
#ifdef USE_MEDIAAPI 		
        MISIRouterLinkIf* link = NULL;     
        link = tmpDevice->GetLink();
#endif /* USE_MEDIAAPI */                       	
        if( connected != tmpDevice->GetDeviceOldState() )
            {
            tmpDevice->SetDeviceOldState( connected );
            const TUint8 deviceIdentifier = tmpDevice->GetDeviceIdentifier();
            tmpDevice->FreeDeviceFM();
#ifdef USE_MEDIAAPI 
            C_TRACE( ( _T( "DISICLTransceiver::ReadStateChanges trxid 0x%x state changed>" ),link->GetTrxId() ) );   
            if( (link->GetTrxId() == iDevPcLastSendTrxId) && (!connected) )
                {
                C_TRACE( ( _T( "DISICLTransceiver::ReadStateChanges trxid 0x%x disconneted>" ),link->GetTrxId() ) );   	
         	      iDevPcLastSendTrxId = iDevPcLastActiveTrxId;
         	      iDevPcLastActiveTrxId = EAmountOfTrxs;  //put a maxvalue	
                } 
#endif /* USE_MEDIAAPI */   					 
            iRouterService->SendDeviceConnectionStateChangedInd( connected, deviceIdentifier );
            }
        else
            {
            tmpDevice->FreeDeviceFM();
            }
        }
    C_TRACE( ( _T( "DISICLTransceiver::ReadStateChanges<" ) ) );
    }
void DISIKernelChannel::HandleDfcRequest(
    TThreadMessage& aMsg
)
{
    C_TRACE( ( _T( "DISIKernelChannel::HandleDfcRequest 0x%x 0x%x 0x%x>" ), this, &aMsg, iObjId ) );
    TThreadMessage& m = ( aMsg );
    TInt request( m.iValue );
    ASSERT_RESET_ALWAYS( m.iArg, ( EISIKernelChannelNullParam | EDISIKernelChannelId << KClassIdentifierShift ) );
    ASSERT_RESET_ALWAYS( EISILastAsyncRequest > ( request ), ( EISIKernelChannelWrongRequest1 | EDISIKernelChannelId << KClassIdentifierShift ) );
    if( iRequests->IsPending( request) )
    {
        C_TRACE( ( _T( "DISIKernelChannel::HandleDfcRequest existing 0x%x request 0x%x" ), this, request ) );
        // Should not give same request object twice before completing the first one.
        ASSERT_RESET_ALWAYS( 0, ( EISIKernelChannelSameRequestTwice | iObjId << KObjIdShift | static_cast<TUint8>( request ) << KExtraInfoShift ) );
    }
    else
    {
        C_TRACE( ( _T( "DISIKernelChannel::HandleDfcRequest 0x%x handling %d" ), this, request ) );
        TUint32* tablePtr = reinterpret_cast<TUint32*>( m.Ptr0() );
        TRequestStatus* dfcStatus = reinterpret_cast<TRequestStatus*>( tablePtr[ KFirstParam ] );
        TDfc* dfc = reinterpret_cast<TDfc*>( tablePtr[ KThirdParam ] );
        ASSERT_RESET_ALWAYS( dfcStatus, ( EISIKernelChannelNullParam2 | EDISIKernelChannelId << KClassIdentifierShift ) );
        ASSERT_RESET_ALWAYS( dfc, ( EISIKernelChannelNullParam3 | EDISIKernelChannelId << KClassIdentifierShift ) );
        iRequests->SetPending( request, dfc, dfcStatus );
        switch( request )
        {
        case EISIAsyncReceive:
        {
            ASSERT_RESET_ALWAYS( !iPtrPtrToRxBuf, ( EISIKernelChannelRxBufferNotReleased | EDISIKernelChannelId << KClassIdentifierShift ) );
            iPtrPtrToRxBuf = reinterpret_cast<TDes8**>( tablePtr[ KSecondParam ] );
            C_TRACE( ( _T( "DISIKernelChannel::HandleDfcRequest EIADAsyncReceive 0x%x 0x%x 0x%x" ), this, iPtrPtrToRxBuf, &iPtrPtrToRxBuf ) );
            iEmptyRxDfc->Enque();
            break;
        }
        default:
        {
            ASSERT_RESET_ALWAYS( 0, ( EISIKernelChannelWrongRequest2 | EDISIKernelChannelId << KClassIdentifierShift ) );
            break;
        }
        }
    }
    C_TRACE( ( _T( "DISIKernelChannel::HandleDfcRequest 0x%x 0x%x 0x%x<" ), this, &aMsg, iObjId ) );
}
// -----------------------------------------------------------------------------
// DIscDevice::Install
// Complete the installation of driver
// ( other items were commented in a header ).
// -----------------------------------------------------------------------------
//
TInt DIscDevice::Install()
    {
    C_TRACE( ( _T( "DIscDevice::Install()" ) ) );

    // Dfc for sending frames
    iSendDfc = new TDfc( Flush, this, Kern::DfcQue0(), KSendDfcPriority );
    iNotifyDfc = new TDfc( NotifyConnection, this, Kern::DfcQue0(), KNotifyDfcPriority );        
    ASSERT_RESET_ALWAYS( iSendDfc, "IscDriver",EIscMemoryAllocationFailure );

    //Initialize IscChannelContainer
    IscChannelContainer::Initialize();
    
    // connect to multiplexer and data transmission driver
    TInt r = InitializeLdd2LddInterface();
    if ( r != KErrNone )
        {
        TRACE_ASSERT_ALWAYS;
        return r;
        }

    return ( SetName( &KIscDriverName ) );
    }
DIsaAccessExtension::~DIsaAccessExtension
        (
        // None
        )
    {

    C_TRACE( ( _T( "DIsaAccessExtension::~DIsaAccessExtension ->" ) ) );
    // Never unloaded so no actual need for these, but we could test memory allocations
    // and deallocations if we destroy this extension in test code.
    delete iRouter;
    iRouter = NULL;
    for( TInt i( 0 ); i < EIADSizeOfDfcThreadList; ++i )
        {
        TDfcQue* dfcQueueToBeDeleted = GetDFCThread( static_cast< TIADDfcThread >( i ) );
        ASSERT_RESET_ALWAYS( dfcQueueToBeDeleted, EIADDFCThreadGetFailed | EIADFaultIdentifier1 << KFaultIdentifierShift );
        delete dfcQueueToBeDeleted;
        dfcQueueToBeDeleted = NULL;
        }
    iDfcQueueList[ EIADLddDfcQueue ] = NULL;
    iDfcQueueList[ EIADExtensionDfcQueue ] = NULL;
    C_TRACE( ( _T( "DIsaAccessExtension::~DIsaAccessExtension <-" ) ) );

    }
TBool DISIRouter::CheckUIDUniqueness( const TInt32 aUID )
    {
    TBool ret(EFalse);
    // No tracing with mutex
    for( TInt i( 0 ); i < KMaxAmountOfObjId; i++ )
        {
        if( iClientTable[ i ]  && ( iClientTable[ i ]->iUID == aUID ) )
            {
#ifndef WITHOUT_WRAPPERS_IN_USE
            if( aUID <= KLastKernelChannel )
                {
                ret = ETrue;
                }
            else
                {
#endif //WITHOUT_WRAPPERS_IN_USE
                ASSERT_RESET_ALWAYS( 0, ( EISIRouterNotUniqueUID | EDISIRouterTraceId << KClassIdentifierShift ) );
#ifndef WITHOUT_WRAPPERS_IN_USE
                }
#endif //WITHOUT_WRAPPERS_IN_USE
            }
        }
    return ret;
    }
// -----------------------------------------------------------------------------
// DIscDevice::Initialize
// Complete the initialization of driver
// ( other items were commented in a header ).
// -----------------------------------------------------------------------------
//
void DIscDevice::Initialize()
    {
    C_TRACE( ( _T( "DIscDevice::Initialize()" ) ) );

    TInt i( 0 );

    // Get buffer configuration data from multiplexer
    TIscConfiguration configData;
    iIscMultiplexerInterface->GetConfiguration( configData );

    // Create main buffer  
    iIscMainRcvBuffer = new DIscMainRcvBuffer( this, configData.mainRcvQueueSize );
    ASSERT_RESET_ALWAYS( iIscMainRcvBuffer, "IscDriver",EIscMemoryAllocationFailure );
    
    // Do second phase installation    
    iIscMainRcvBuffer->DoCreate();
    
    // Create queue for sending frames
    iSend = new TUint32*[configData.channelSendQueueSize];
    ASSERT_RESET_ALWAYS( iSend, "IscDriver",EIscMemoryAllocationFailure );
    
    iSendFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize];
    for ( i = 0; i < configData.channelSendQueueSize; i++ )
        {
        iSendFrameParameters[i] = new TIscSendFrameInfo;
        }
    ASSERT_RESET_ALWAYS( iSendFrameParameters, "IscDriver",EIscMemoryAllocationFailure );

    iSendQueue = new DIscSendQueue( iSend, iSendFrameParameters, configData.channelSendQueueSize );
    ASSERT_RESET_ALWAYS( iSendQueue, "IscDriver",EIscMemoryAllocationFailure );


    // create temporary queue
    iTempSend = new TUint32*[configData.channelSendQueueSize];
    ASSERT_RESET_ALWAYS( iTempSend, "IscDriver",EIscMemoryAllocationFailure );

    iTempFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize];
    for ( i =0; i < configData.channelSendQueueSize; i++ )
        {
        iTempFrameParameters[i] = new TIscSendFrameInfo;
        }
    ASSERT_RESET_ALWAYS( iTempFrameParameters, "IscDriver",EIscMemoryAllocationFailure );

    iTempQueue = new DIscSendQueue( iTempSend, iTempFrameParameters, configData.channelSendQueueSize );
    ASSERT_RESET_ALWAYS( iTempQueue, "IscDriver",EIscMemoryAllocationFailure );


    // Create send queue for control channel
    iControlSend = new TUint32*[configData.channelSendQueueSize];
    ASSERT_RESET_ALWAYS( iControlSend, "IscDriver",EIscMemoryAllocationFailure );

    iControlFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize];
    for ( i = 0; i < configData.channelSendQueueSize; i++ )
        {
        iControlFrameParameters[i] = new TIscSendFrameInfo;
        }
    ASSERT_RESET_ALWAYS( iControlFrameParameters, "IscDriver",EIscMemoryAllocationFailure );

    iControlSendQueue = new DIscSendQueue( iControlSend, iControlFrameParameters, configData.channelSendQueueSize );
    ASSERT_RESET_ALWAYS( iControlSendQueue, "IscDriver",EIscMemoryAllocationFailure );
    
    iIscDataTransmissionInterface->AllocBuffers( configData.bufferConfig );
    
    iConnectionStatus = iIscDataTransmissionInterface->ConnectionStatus();

    iIscMultiplexerInterface->NotifyConnectionStatus( iConnectionStatus );
    C_TRACE( ( _T( "DIscDevice::Initialize - return void" ) ) );
    }
TInt DISICLTransceiver::RouteISIMessage(
        TDes8& aMessage,
        TBool aDynamicSenderCheckNeeded
        )
    {
    C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage 0x%x 0x%x> len %d" ), &aMessage, aDynamicSenderCheckNeeded, aMessage.Length() ) );
    const TUint8* msgPtr = aMessage.Ptr();
    ISIMESSAGE_TRACE( aMessage );
    TInt error( ValidateISIMessage( aMessage ) );
    if( KErrNone != error )
        {
        TRACE_ASSERT_ALWAYS;
        C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage invalid message 0x%x" ), &aMessage ) );
        MemApi::DeallocBlock( aMessage );
        }
    else
        {
        TBool sendOk( EFalse );
        if ( aDynamicSenderCheckNeeded )// Save dynamic device ids from PN_DEV_OWN
            {
            C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage from ISI Router" ) ) );
            TUint8 txDeviceIdentifier = GET_SENDER_DEV( aMessage );
            if ( DynamicDevice( txDeviceIdentifier ) )
                {
                C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage from ISI Router Dynamic Dev" ) ) );                
                UpdateDynamicDeviceTable( txDeviceIdentifier, PN_DEV_OWN );
#ifndef USE_MEDIAAPI 				
                ASSERT_RESET_ALWAYS( txDeviceIdentifier == PN_DEV_PC, 0xdeaddead );// only supported PN_DEV_PC with EIscNokiaUsbPhonetLink
#endif /* USE_MEDIAAPI */  					
                }
            }

        TUint8 rxDeviceIdentifier = GET_RECEIVER_DEV( aMessage );
        C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage rxDeviceIdentifier 0x%x" ), rxDeviceIdentifier ) );
        
        if ( DynamicDevice( rxDeviceIdentifier ) )
            {            
            DynamicToStaticDevice( rxDeviceIdentifier );            
            C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage rxDeviceIdentifier after 0x%x" ), rxDeviceIdentifier ) );
            }


        if( rxDeviceIdentifier == PN_DEV_OWN )
            {
            C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage PN_DEV_OWN 0x%x" ), &aMessage ) );
            TUint16 objId(0xffff);
#ifndef USE_MEDIAAPI 
            if ( GET_RECEIVER_DEV( aMessage ) == PN_DEV_PC )
                {
                C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage to PN_DEV_PC in PN_DEV_OWN" )) );
                objId = EIscNokiaUsbPhonetLink;
                }
            else
                {
                objId = GET_RECEIVER_OBJ( aMessage );
                }
#endif /* USE_MEDIAAPI */  					
#ifdef USE_MEDIAAPI 
            objId = GET_RECEIVER_OBJ( aMessage );
#endif /* USE_MEDIAAPI */  				
            sendOk = iShRouter.Receive( aMessage, objId );
            C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage PN_DEV_OWN 0x%x ok %d" ), &aMessage, sendOk ) );
            }        
        else
            {
            C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage Not PN_DEV_OWN 0x%x" ), &aMessage ) );
            MISIRouterLinkIf* link = NULL;


            const TInt count( iShDevices.Count() );
            for( TInt index( 0 ); index < count; index++ )
                {
                DISIDevice* tmpDevice = iShDevices[ index ];
                ASSERT_RESET_ALWAYS( tmpDevice, ( EISICLTransceiverNULLPtr4 | EDISICLTransceiverTraceId << KClassIdentifierShift ) );
                tmpDevice->LockDeviceFM();
                if( tmpDevice->GetDeviceIdentifier() == rxDeviceIdentifier ) 
                    {
                    link = tmpDevice->GetLink();
                    tmpDevice->FreeDeviceFM();
#ifndef USE_MEDIAAPI 					
                    sendOk = link->Send( aMessage );
                    break;
#endif /* USE_MEDIAAPI */  	
#ifdef USE_MEDIAAPI 						
                    if ( GET_RECEIVER_DEV( aMessage ) == PN_DEV_PC )
                        {
                        C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage PN_DEV_PC %d, %d" ), link->GetTrxId(), iDevPcLastSendTrxId ) ); 	
                        if(iDevPcLastSendTrxId < EAmountOfTrxs)
                            {	
                            if ( link->GetTrxId() ==	iDevPcLastSendTrxId )
                                {
                                if (link->StateConnected())
                                    {
                                    C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage PN_DEV_PC %d, Msg mediaid 0x%x" ), link->GetTrxId(), msgPtr[ ISI_HEADER_OFFSET_MEDIA ] ) ); 
                                    sendOk = link->Send( aMessage );
                                    break;
                                    }
                                }
                            }    
                        else
                            {
                            break;	
                            }		   	
		                 }
                    else
                    	{    			
                        sendOk = link->Send( aMessage );
                        break;
                        }
#endif /* USE_MEDIAAPI */  							
                    }    
                else
                    {
                    tmpDevice->FreeDeviceFM();
                    }
                }
            C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage Not PN_DEV_OWN ok %d" ), &aMessage, sendOk ) );
            }
        if( !sendOk )
            {
            TRACE_ASSERT_ALWAYS;
            error = SendCommIsaEntityNotReachableResp( aMessage );
            }
        }
    C_TRACE( ( _T( "DISICLTransceiver::RouteISIMessage 0x%x<" ), &aMessage ) );
    return error;
    }
TInt DISIKernelChannel::HandleSyncRequest(
    TThreadMessage& aMsg
)
{
    C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest 0x%x 0x%x 0x%x>" ), this, &aMsg, iObjId ) );
    TThreadMessage& m = ( aMsg );
    TInt request( m.iValue );
    ASSERT_RESET_ALWAYS( m.iArg, ( EISIKernelChannelNullParam4 | EDISIKernelChannelId << KClassIdentifierShift ) );
    TInt returnValue( KErrNone );
    C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest 0x%x handling %d" ), this, request ) );
    TUint32* tablePtr = reinterpret_cast<TUint32*>( m.Ptr0() );

    switch( request )
    {
    case EISIConnect:
    {
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISIConnect 0x%x" ), this ) );
        iUID = tablePtr[ KFirstParam ];
        TUint8* objIdPtr = reinterpret_cast<TUint8*>( tablePtr[ KSecondParam ] );
        C_TRACE( ( _T( "DISIKernelChannel::HandleDfcRequest EISINokiaKernelOpen 0x%x" ), this ) );
        iRouterIf->Connect( iUID, iObjId, this );
        *objIdPtr = iObjId;
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISIConnect 0x%x" ), this ) );
        break;
    }
    case EISIDisconnect:
    {
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISIDisconnect 0x%x" ), this ) );
        Disconnect();
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISIDisconnect 0x%x" ), this ) );
        returnValue = KErrNone;
        break;
    }
    case EISIAllocateBlock:
    {
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISIAllocateBlock 0x%x" ), this ) );
        const TInt size = *reinterpret_cast<TInt*>( tablePtr[ KFirstParam ] );
        TDes8*& block = *(reinterpret_cast<TDes8**>( tablePtr[ KSecondParam ] ));
        C_TRACE( ( _T( "DISIKernelChannel:: EISIAllocateBlock 0x%x block 0x%x %d" ), this, block, size ) );
        block = ( &MemApi::AllocBlock( size ) );
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISIAllocateBlock 0x%x" ), this ) );
        break;
    }
    case EISIDeallocateBlock:
    {
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISIDeallocateBlock 0x%x" ), this ) );
        TDes8& block = *reinterpret_cast<TDes8*>( tablePtr[ KFirstParam ] );
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISIAllocateBlock 0x%x block 0x%x" ), this, &block ) );
        // Needed to ensure that right channel is deleting the right block. (Could it be done otherways too?)
        if( iPtrPtrToRxBuf )
        {
            if ( &block == *iPtrPtrToRxBuf )
            {
                C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest release 0x%x 0x%x clientRx 0x%x"), iPtrPtrToRxBuf, &iPtrPtrToRxBuf, *iPtrPtrToRxBuf ) );
                iPtrPtrToRxBuf = NULL;
            }
        }
        MemApi::DeallocBlock( block );
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISIDeallocateBlock 0x%x" ), this ) );
        break;
    }
    case EISISend:
    {
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISISend 0x%x" ), this ) );
        TDes8& block = *reinterpret_cast<TDes8*>( tablePtr[ KFirstParam ] );
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISISend 0x%x block 0x%x" ), this, &block ) );
        returnValue = iRouterIf->Send( block, iObjId );
        C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest EISISend 0x%x" ), this ) );
        break;
    }
    default:
    {
        ASSERT_RESET_ALWAYS( 0, ( EISIKernelChannelWrongRequest3 | EDISIKernelChannelId << KClassIdentifierShift ) );
        break;
    }
    }
    C_TRACE( ( _T( "DISIKernelChannel::HandleSyncRequest 0x%x 0x%x %d 0x%x<" ), this, &aMsg, returnValue, iObjId ) );
    return returnValue;
}