diff -r 37b610eb7fe3 -r b5894bb67e73 systemswstubs/examplecommonisc/IscDriver/src/IscChannel.cpp --- a/systemswstubs/examplecommonisc/IscDriver/src/IscChannel.cpp Thu Aug 19 09:36:39 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1800 +0,0 @@ -/* -* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "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: An example implementation for ISC Driver Reference -* -*/ - - - -// INCLUDE FILES -#include -#include -#include "IscChannel.h" -#include "IscDevice.h" -#include "IscChannelContainer.h" -#include "IscQueue.h" -#include "IscTrace.h" - -// EXTERNAL DATA STRUCTURES - -// EXTERNAL FUNCTION PROTOTYPES - -// CONSTANTS -_LIT( KIscDriver, "IscDriver" ); - -// MACROS - -// LOCAL CONSTANTS AND MACROS -const TInt KIscInitializeDfcPriority( 1 ); -const TInt KOneParam( 1 ); -const TInt KTwoParams( 2 ); -const TInt KThreeParams( 3 ); -const TInt KFirstParam( 0 ); -const TInt KSecondParam( 1 ); -const TInt KThirdParam( 2 ); -const TInt KMultiplyByOne( KSecondParam ); -const TInt KMultiplyByThree( KThreeParams ); -const TInt KDivideByFour( 4 ); - -// MODULE DATA STRUCTURES - -// LOCAL FUNCTION PROTOTYPES - -// FORWARD DECLARATIONS - - -// ============================ MEMBER FUNCTIONS =============================== - - -// ----------------------------------------------------------------------------- -// DIscChannel::DIscChannel -// C++ default constructor. -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -EXPORT_C DIscChannel::DIscChannel( DLogicalDevice* aDevice ) - : iInitializeDfc( NULL ), - iDataTransmissionIniData( NULL ), - iMultiplexerIniData( NULL ), - iMultiplexerBuffer( NULL ), - iDataTransmissionBuffer( NULL ), - iIscDevice( NULL ), - iIscConnectionStatusPtr( NULL ), - iIscFlowControlStatusPtr( NULL ), - iReceiveBufPtr( NULL ), - iDataReceiveBufPtr( NULL ), - iNeededBufLen( NULL ), - iNeededDataBufLen( NULL ), - iChannelNumber( 0 ), - iChannelOpen( EFalse ), - iFrameRx( NULL ), - iFrameRxQueue( NULL ), - iDataFrameRx( NULL ), - iDataFrameRxQueue( NULL ), - iULFlowControlStatus( EIscFlowControlOff ), - iDLFlowControlStatus( EIscFlowControlOff ), - iLastNotifiedULFlowstatus( EIscFlowControlOff ), - iIscChannelHighWaterMark( 0 ), - iIscChannelLowWaterMark( 0 ), - iOverFlow( EFalse ), - iClientPanic( EFalse ), - iDataTransmissionErrorCode( KErrNone ) - { - - iIscDevice = ( DIscDevice * )aDevice; - for ( TInt i( KErrNone ); i < EIscAsyncLast; i++ ) - { - iIscRequests[i] = NULL; - } - iThread = &Kern::CurrentThread(); - TInt r = iThread->Open(); - TRACE_ASSERT( r == KErrNone ); - - } - - -// ----------------------------------------------------------------------------- -// DIscChannel::~DIscChannel -// Destructor -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -DIscChannel::~DIscChannel() - { - C_TRACE( ( _T( "DIscChannel::~DIscChannel()" ) ) ); - - if ( iChannelNumber < KIscNumberOfUnits ) - { - IscChannelContainer::RemoveChannel( this ); - } - else - { - C_TRACE( ( _T( "DIscChannel::~DIscChannel() re-open" ) ) ); - } - - ChannelDestruction(); - Kern::SafeClose( ( DObject*& )iThread, NULL ); - C_TRACE( ( _T( "DIscChannel::~DIscChannel() SafeClose called" ) ) ); - - } - -// ----------------------------------------------------------------------------- -// DIscChannel::ChannelDestruction -// Destructor -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::ChannelDestruction() - { - C_TRACE( ( _T( "DIscChannel::ChannelDestruction() iChannelNumber (0x%x)" ),iChannelNumber ) ); - - // call DIscMultiplexerBase::CloseDLC and DLFlowControlNotify in case the channel has not been - // properly closed ( e.g. client thread panic etc. ) - if ( iChannelOpen ) - { - iIscDevice->CancelSending( iChannelNumber, this );// Delete pending send frames - iIscDevice->iIscMultiplexerInterface->CloseDLC( iChannelNumber, this ); - iIscDevice->DLFlowControlNotify( EIscFlowControlOff, iChannelNumber, this ); - } - - if ( iFrameRxQueue ) - { - while ( !iFrameRxQueue->Empty() ) - { - TDes8* tempPtr = ( TDes8* ) iFrameRxQueue->GetFirst(); - iFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( tempPtr ); - } - delete iFrameRxQueue; - iFrameRxQueue = NULL; - } - - if ( iFrameRx ) - { - delete [] iFrameRx; - iFrameRx = NULL; - } - - if ( iDataFrameRxQueue ) - { - while ( !iDataFrameRxQueue->Empty() ) - { - TDes8* tempPtr = ( TDes8* ) iDataFrameRxQueue->GetFirst(); - iDataFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( tempPtr ); - } - delete iDataFrameRxQueue; - iDataFrameRxQueue = NULL; - } - - if ( iDataFrameRx ) - { - delete [] iDataFrameRx; - iDataFrameRx = NULL; - } - - if ( iInitializeDfc ) - { - delete iInitializeDfc; - iInitializeDfc = NULL; - } - - if ( iDataTransmissionIniData ) - { - Kern::Free( iDataTransmissionBuffer ); - delete iDataTransmissionIniData; - iDataTransmissionIniData = NULL; - } - - if ( iMultiplexerIniData ) - { - Kern::Free( iMultiplexerBuffer ); - delete iMultiplexerIniData; - iMultiplexerIniData = NULL; - } - - C_TRACE( ( _T( "DIscChannel::ChannelDestruction - return void" ) ) ); - } - -// ----------------------------------------------------------------------------- -// DIscChannel::HandleMsg -// Message handling ( kernel server context ). -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::HandleMsg( - TMessageBase* aMsg ) - { - C_TRACE( ( _T( "DIscChannel::HandleMsg(0x%x)" ), aMsg ) ); - TThreadMessage& m=*( TThreadMessage* )aMsg; - TInt id( m.iValue ); - - if ( id==( TInt )ECloseMsg ) - { - C_TRACE( ( _T( "DIscChannel::HandleMsg ECloseMsg" ) ) ); - m.Complete( KErrNone,EFalse ); - return; - } - - else if ( id==KMaxTInt ) - { - // DoCancel - // Should not come here ever - ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscNotAllowedCallToDoCancel ); - } - - else if ( id<0 ) - { - // DoRequest - // should not come here ever - ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscNotAllowedCallToDoRequest ); - } - - else - { - // DoControl - TUint32 a1[ KThreeParams ]; - TInt r( KErrNone ); - if ( id != EIscSyncClose ) - { - TInt amountOfParams( KErrNone ); - switch( id ) - { - case EIscAsyncInitializeModemInterface: - case EIscAsyncOpen: - amountOfParams = KThreeParams; - break; - default: - ASSERT_RESET_ALWAYS( 0, "NokiaISCDriver", EIscUnknownCommand ); - break; - } - r = Kern::ThreadRawRead( iThread, ( TAny* )m.Ptr0(), a1, - amountOfParams * sizeof( TAny* ) ); - TRACE_ASSERT( r == KErrNone ); - } - if( r == KErrNone ) - { - r=HandleRequest( id,a1,m.Ptr1() ); - } - - m.Complete( r,ETrue ); - } - } - -// ----------------------------------------------------------------------------- -// DIscChannel::Request -// Message handling ( user thread context ). -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -#ifndef COMPONENT_TRACE_FLAG -TInt DIscChannel::Request( TInt aReqNo, TAny* a1, TAny* ) -#else -TInt DIscChannel::Request( TInt aReqNo, TAny* a1, TAny* a2) -#endif - { - C_TRACE( ( _T( "DIscChannel::Request(0x%x, 0x%x, 0x%x)" ), aReqNo, a1, a2 ) ); - - TInt r( KErrNotFound ); - - if ( aReqNo<( TInt )EMinRequestId ) - C_TRACE( ( _T( "DIscChannel::Request ERROR: False aReqNo %d" ), aReqNo ) ); - - if ( aReqNo >= 0 && aReqNo < EIscAsyncLastKernelServerContext || - aReqNo >= EIscAsyncLast && aReqNo < EIscSyncLastKernelServerContext ) - { - TThreadMessage& m=Kern::Message(); - m.iValue=aReqNo; - m.iArg[ KFirstParam ]=a1; - m.iArg[ KSecondParam ]=NULL; - r = m.SendReceive( &iMsgQ ); - } - else - { - TInt ulen( KErrNotFound ); - switch ( aReqNo ) - { - case EIscCancelAsyncInitialize: - case EIscCancelAsyncReceive: - case EIscCancelAsyncDataReceive: - case EIscSyncGetConnectionStatus: - case EIscCancelAsyncNotifyConnection: - case EIscSyncGetFlowControlStatus: - case EIscCancelAsyncNotifyFlowControl: - case EIscSyncGetMaximunDataSize: - case EIscCancelAsyncCustomOperation1: - case EIscCancelAsyncCustomOperation2: - case EIscCancelAsyncCustomOperation3: - case EIscCancelAsyncCustomOperation4: - case EIscCancelAsyncCustomOperation5: - case EIscCancelAsyncOpen: - case EIscSyncResetBuffers: - case EIscCancelAsyncSend: - case EIscCancelAsyncDataSend: - { - ulen = KErrNone; - break; - } - case EIscSyncSend: - case EIscSyncDataSend: - case EIscSyncCustomOperation1: - case EIscSyncCustomOperation2: - case EIscSyncCustomOperation3: - case EIscSyncCustomOperation4: - case EIscSyncCustomOperation5: - case EIscAsyncClose: - { - ulen = KOneParam; - break; - } - case EIscAsyncSend: - case EIscAsyncDataSend: - case EIscSyncGetChannelInfo: - case EIscAsyncNotifyConnectionStatus: - case EIscAsyncNotifyFlowControlStatus: - case EIscAsyncCustomOperation1: - case EIscAsyncCustomOperation2: - case EIscAsyncCustomOperation3: - case EIscAsyncCustomOperation4: - case EIscAsyncCustomOperation5: - { - ulen = KTwoParams; - break; - } - case EIscAsyncReceive: - case EIscAsyncDataReceive: - { - ulen = KThreeParams; - break; - } - default: - { - TRACE_ASSERT_ALWAYS; - } - } - ASSERT_RESET_ALWAYS( KErrNotFound != ulen, "ISCDriver", EIscUnknownCommand ); - // Maximum number of elements is three!!! - TAny* kptr[ KThreeParams ] = { KErrNone }; - if( ulen > KErrNone ) - { - C_TRACE( ( _T( "DIscChannel::Request ISC kumemget32" ) ) ); - kumemget32( kptr , a1, ( sizeof( TAny* ) ) * ulen ); - } - r = HandleRequest( aReqNo, kptr, NULL ); - } - C_TRACE( ( _T( "DIscChannel::Request ISC return %d CH 0x%x" ), r, iChannelNumber ) ); - return r; - - } - -// ----------------------------------------------------------------------------- -// DIscChannel::DoControl -// Handles requests. -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -TInt DIscChannel::HandleRequest( - TInt aFunction, - TAny* a1, - TAny* /*a2*/ ) - { - C_TRACE( ( _T( "DIscChannel::DoControl(0x%x, 0x%x) iChannelNumber 0x%x channelPtr 0x%x" ), aFunction, a1, iChannelNumber, this ) ); - - TInt error( KErrNone ); - -#ifdef _DEBUG - // Check if control frame buffer overflow -> panic - if ( iClientPanic ) - { - C_TRACE( ( _T( "DIscChannel::DoControl() BUFFER OVERFLOW: PANIC CLIENT 0x%x" ), iChannelNumber ) ); - TRACE_ASSERT_ALWAYS; - // This panic the user thread only. - Kern::ThreadKill( iThread, EExitPanic, EIscControlBufferOverflow, KIscDriver ); - } -#endif // _DEBUG - - // Handle asynchronous requests - if ( aFunction >= EIscAsyncInitializeModemInterface && - aFunction < EIscAsyncLast ) - { - // if request is already active - if ( iIscRequests[aFunction] ) - { - TUint32* tablePtr = ( TUint32* )a1; - TRequestStatus* requestStatus = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - Kern::RequestComplete( iThread, requestStatus, KErrAlreadyExists ); - } - else - { - HandleAsyncRequest( aFunction, a1 ); - } - } - // Handle synchronous requests. - else if ( aFunction >= EIscAsyncLast && - aFunction < EIscSyncLast ) - { - error = HandleSyncRequest( aFunction, a1 ); - } - // Handle cancellation requests. - else if ( aFunction >= EIscSyncLast && - aFunction < EIscCancelLast ) - { - error = HandleCancelRequest( aFunction, a1 ); - } - // Undefined request, panic current thread. - else - { - // This panic the user thread only. - Kern::ThreadKill( iThread, EExitPanic, EIscControlBufferOverflow, KIscDriver ); - } - - C_TRACE( ( _T( "DIscChannel::DoControl - return %d" ), error ) ); - - return error; - } - - -// ----------------------------------------------------------------------------- -// DIscChannel::HandleAsyncRequests -// Handles asynchronous client requests -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::HandleAsyncRequest( - TInt aFunction, - TAny* a1 ) - { - C_TRACE( ( _T( "DIscChannel::HandleAsyncRequest(0x%x, 0x%x) channelPtr 0x%x" ), aFunction, a1, this ) ); - - TUint32* tablePtr = ( TUint32* )a1; - - switch ( aFunction ) - { - case EIscAsyncInitializeModemInterface: - { - TInt r = KErrNotFound; - iIscRequests[EIscAsyncInitializeModemInterface] = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - - iInitializeDfc = new TDfc( InitializeComplete, this, Kern::DfcQue0(), KIscInitializeDfcPriority ); - ASSERT_RESET_ALWAYS( iInitializeDfc, "IscDriver",EIscMemoryAllocationFailure ); - - // Get Data Transmission Driver initialization string - TDesC8* tempPtr = ( TDesC8* )tablePtr[ KThirdParam ]; - iDataTransmissionBuffer = ( TUint8* )Kern::Alloc( KIscIniLineLength ); - ASSERT_RESET_ALWAYS( iDataTransmissionBuffer, "IscDriver",EIscMemoryAllocationFailure ); - - iDataTransmissionIniData = new ( TPtr8 )( iDataTransmissionBuffer, KIscIniLineLength ); - ASSERT_RESET_ALWAYS( iDataTransmissionIniData, "IscDriver",EIscMemoryAllocationFailure ); - - r = Kern::ThreadDesRead( iThread, tempPtr, *iDataTransmissionIniData, 0, KChunkShiftBy0 ); - ASSERT_RESET_ALWAYS( r == KErrNone, "IscDriver",EIscMemoryAllocationFailure ); - - // Get Multiplexer initialization string - tempPtr = ( TDesC8* )tablePtr[1]; - iMultiplexerBuffer = ( TUint8* )Kern::Alloc( KIscIniLineLength ); - ASSERT_RESET_ALWAYS( iMultiplexerBuffer, "IscDriver",EIscMemoryAllocationFailure ); - - iMultiplexerIniData = new ( TPtr8 )( iMultiplexerBuffer, KIscIniLineLength ); - ASSERT_RESET_ALWAYS( iDataTransmissionIniData, "IscDriver",EIscMemoryAllocationFailure ); - - r = Kern::ThreadDesRead( iThread, tempPtr, *iMultiplexerIniData, 0, KChunkShiftBy0 ); - ASSERT_RESET_ALWAYS( r == KErrNone, "IscDriver",EIscMemoryAllocationFailure ); - - // If buffer configuration is given from isc_config.ini as multiplexer configuration string, multiplexer - // needs configuration before datatransmissin driver is initialized - iIscDevice->iIscMultiplexerInterface->SetInitializationParameters( *iMultiplexerIniData ); - - // Allocate buffers and receive queues - iIscDevice->Initialize(); - - iIscDevice->iIscDataTransmissionInterface->InitializeDataTransmission( *iDataTransmissionIniData, - iInitializeDfc, - iDataTransmissionErrorCode ); - break; - } - - case EIscAsyncOpen: - { - iIscRequests[EIscAsyncOpen] = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - if ( iIscDevice->ConnectionStatus() == EIscConnectionOk ) - { - TDesC8* openInfo = ( TDesC8* )tablePtr[ KThirdParam ]; - // Channel info parameter has to be copied from user side in Epoc Kernel Architecture 2 - TInt length = Kern::ThreadGetDesLength( iThread, ( TDesC8* )tablePtr[ KThirdParam ] ); - TUint8* buffer = NULL; - TPtr8* bufferPtr = NULL; - if ( length > KErrNone ) - { - C_TRACE( ( _T( "DIscChannel::HandleAsyncRequest EIscAsyncOpen channel info got" ) ) ); - buffer = ( TUint8* )Kern::Alloc( length ); - bufferPtr = new ( TPtr8 )( buffer, length ); - TInt r = Kern::ThreadDesRead( iThread, openInfo, *bufferPtr, 0, KChunkShiftBy0 ); - ASSERT_RESET_ALWAYS( r == KErrNone, "IscDriver",EIscMemoryAllocationFailure ); - openInfo = ( TDesC8* )bufferPtr; - } - iIscDevice->iIscMultiplexerInterface->OpenDLC( ( TUint16 )tablePtr[ KSecondParam ], - openInfo, - this ); - - if ( buffer ) - Kern::Free( buffer ); - if ( bufferPtr ) - { - delete bufferPtr; - bufferPtr = NULL; - } - } - else - { - CompleteRequest( aFunction, KErrNotReady ); - } - break; - } - case EIscAsyncSend: - { - iIscRequests[EIscAsyncSend] = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - if ( iIscDevice->ConnectionStatus() == EIscConnectionOk - && iULFlowControlStatus == EIscFlowControlOff ) - { - TDesC8* ptr = ( TDesC8* ) tablePtr[ KSecondParam ]; - - // No return values check needed. Request completed with error value by multiplexer - iIscDevice->iIscMultiplexerInterface->Send( ( TUint16 )aFunction, - iChannelNumber, - *ptr, - this ); - } - else - { - if ( iULFlowControlStatus != EIscFlowControlOff ) - { - CompleteRequest( aFunction, KErrOverflow ); - } - else - { - CompleteRequest( aFunction, KErrNotReady ); - } - } - break; - } - case EIscAsyncReceive: - { - TRACE_ASSERT( tablePtr[ KFirstParam ] ); - TRACE_ASSERT( tablePtr[ KSecondParam ] ); - TRACE_ASSERT( tablePtr[ KThirdParam ] ); - - // check for descriptor validity - TRACE_ASSERT( Kern::ThreadGetDesMaxLength( iThread, (TPtr8* )tablePtr[KSecondParam] ) > 0 ); - - //Store needed length ptr - iNeededBufLen = ( TPtr8* )tablePtr[ KThirdParam ]; - - //Store msg data ptr - iReceiveBufPtr = ( TPtr8* )tablePtr[ KSecondParam ]; - - iIscRequests[EIscAsyncReceive] = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - - break; - } - case EIscAsyncDataSend: - { - iIscRequests[EIscAsyncDataSend] = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - - if ( iIscDevice->ConnectionStatus() == EIscConnectionOk - && iULFlowControlStatus == EIscFlowControlOff ) - { - TDesC8* ptr = ( TDesC8* )tablePtr[ KSecondParam ]; - iIscDevice->iIscMultiplexerInterface->DataSend( ( TUint16 )aFunction, - iChannelNumber, - *ptr, - this ); - } - else - { - if ( iULFlowControlStatus != EIscFlowControlOff ) - { - CompleteRequest( aFunction, KErrOverflow ); - } - else - { - CompleteRequest( aFunction, KErrNotReady ); - } - } - break; - } - case EIscAsyncDataReceive: - { - TRACE_ASSERT( tablePtr[ KFirstParam ] ); - TRACE_ASSERT( tablePtr[ KSecondParam ] ); - TRACE_ASSERT( tablePtr[ KThirdParam ] ); - - // check for descriptor validity - TRACE_ASSERT( Kern::ThreadGetDesMaxLength( iThread, (TPtr8* )tablePtr[KSecondParam] ) > 0 ); - - //Store needed length ptr - iNeededDataBufLen = ( TPtr8* )tablePtr[ KThirdParam ]; - - //Store msg data ptr - iDataReceiveBufPtr = ( TPtr8* )tablePtr[ KSecondParam ]; - - iIscRequests[EIscAsyncDataReceive] = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - - break; - } - case EIscAsyncNotifyConnectionStatus: - { - iIscConnectionStatusPtr = ( TPtr8* )tablePtr[ KSecondParam ]; - iIscRequests[EIscAsyncNotifyConnectionStatus] = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - break; - } - case EIscAsyncNotifyFlowControlStatus: - { - iIscFlowControlStatusPtr = reinterpret_cast( tablePtr[ KSecondParam ] ); - iIscRequests[ EIscAsyncNotifyFlowControlStatus ] = reinterpret_cast( tablePtr[ KFirstParam ] ); - C_TRACE( ( _T( "DIscChannel::NotifyFlowControl iLastNotifiedULFlowstatus = %d iULFlowControlStatus = %d" ), iLastNotifiedULFlowstatus, iULFlowControlStatus ) ); - - if( iULFlowControlStatus != iLastNotifiedULFlowstatus ) - { - // Complete immediately. - C_TRACE( ( _T( "DIscChannel::HandleAsyncRequest iULFlowControlStatus != iLastNotifiedULFlowstatus" ) ) ); - NotifyFlowControl( iULFlowControlStatus ); - } - else - { - // None - } - break; - } - case EIscAsyncCustomOperation1: - case EIscAsyncCustomOperation2: - case EIscAsyncCustomOperation3: - case EIscAsyncCustomOperation4: - case EIscAsyncCustomOperation5: - { - iIscRequests[aFunction] = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - TAny* tempPtr = ( TAny* )tablePtr[ KSecondParam ]; - iIscDevice->iIscMultiplexerInterface->CustomFunction( iChannelNumber, - ( TUint16 )aFunction, - tempPtr, - this ); - break; - } - case EIscAsyncClose: - { - iIscRequests[aFunction] = ( TRequestStatus* )( tablePtr[ KFirstParam ] ); - - ResetBuffers(); - - // Cancel all active requests except asynchronous close - for ( TInt i( KErrNone ); i < EIscAsyncLast; i++ ) - { - // if request is active complete it with KErrCancel - if ( iIscRequests[i] && i != EIscAsyncClose ) - { - iIscDevice->iIscMultiplexerInterface->CancelNotify( iChannelNumber, i, this ); - CompleteRequest( i, KErrCancel ); - } - } - - iChannelOpen = EFalse; - - iIscDevice->iIscMultiplexerInterface->CloseDLC( iChannelNumber, this ); - - break; - } - default: - { - ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscUnknownCommand ); - break; - } - } - - IscChannelContainer::AddDfc(); - - } - - -// ----------------------------------------------------------------------------- -// DIscChannel::HandleSyncRequest -// Handles synchronous client requests -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -TInt DIscChannel::HandleSyncRequest( - TInt aFunction, - TAny* a1 ) - { - C_TRACE( ( _T( "DIscChannel::HandleSyncRequest(0x%x, 0x%x) channelPtr 0x%x" ), aFunction, a1, this ) ); - - TInt error( KErrNone ); - TUint32* tablePtr = ( TUint32* )a1; - - switch ( aFunction ) - { - case EIscSyncClose: - { - ResetBuffers(); - - iIscDevice->iIscMultiplexerInterface->CloseDLC( iChannelNumber, this ); - - // Cancel all active requests - for ( TInt i( KErrNone ); i < EIscAsyncLast; i++ ) - { - // if request is active complete it with KErrCancel - if ( iIscRequests[i] ) - { - iIscDevice->iIscMultiplexerInterface->CancelNotify( iChannelNumber, i, this ); - CompleteRequest( i, KErrCancel ); - } - } - - error = KErrNone; - iChannelOpen = EFalse; - break; - } - case EIscSyncSend: - { - if ( iIscDevice->ConnectionStatus() == EIscConnectionOk - && iULFlowControlStatus == EIscFlowControlOff ) - { - - TDesC8* ptr = ( TDesC8* ) tablePtr[ KFirstParam ]; - error = iIscDevice->iIscMultiplexerInterface->Send( ( TUint16 )aFunction, - iChannelNumber, - *ptr, - this ); - } - else - { - if ( iULFlowControlStatus != EIscFlowControlOff ) - { - error = KErrOverflow; - } - else - { - error = KErrNotReady; - } - } - break; - } - case EIscSyncDataSend: - { - if ( iIscDevice->ConnectionStatus() == EIscConnectionOk - && iULFlowControlStatus == EIscFlowControlOff ) - { - TDesC8* ptr = ( TDesC8* ) tablePtr[ KFirstParam ]; - error = iIscDevice->iIscMultiplexerInterface->DataSend( ( TUint16 )aFunction, - iChannelNumber, - *ptr, - this ); - } - else - { - if ( iULFlowControlStatus != EIscFlowControlOff ) - { - error = KErrOverflow; - } - else - { - error = KErrNotReady; - } - } - break; - } - case EIscSyncGetConnectionStatus: - { - error = iIscDevice->ConnectionStatus(); - break; - } - case EIscSyncGetFlowControlStatus: - { - error = iULFlowControlStatus; - break; - } - case EIscSyncGetChannelInfo: - { - TDes8* tempPtr = ( TDes8* ) tablePtr[1]; - error = iIscDevice->iIscMultiplexerInterface->GetChannelInfo( ( TUint16 )tablePtr[ KFirstParam ], - *tempPtr ); - break; - } - case EIscSyncGetMaximunDataSize: - { - error = iIscDevice->iIscMultiplexerInterface->MaximumDataSize( iChannelNumber ); - break; - } - case EIscSyncCustomOperation1: - case EIscSyncCustomOperation2: - case EIscSyncCustomOperation3: - case EIscSyncCustomOperation4: - case EIscSyncCustomOperation5: - { - TAny* tempPtr = ( TAny* )tablePtr[ KFirstParam ]; - error = iIscDevice->iIscMultiplexerInterface->CustomFunction( iChannelNumber, - ( TUint16 )aFunction, - tempPtr, - this ); - break; - } - case EIscSyncResetBuffers: - { - ResetBuffers(); - error = KErrNone; - break; - } - default: - { - ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscUnknownCommand ); - break; - } - } - return error; - } - -// ----------------------------------------------------------------------------- -// DIscChannel::HandleCancelRequest -// Cancels active request -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -TInt DIscChannel::HandleCancelRequest( - TInt aFunction, - TAny* /*a1*/ ) - { - C_TRACE( ( _T( "DIscChannel::HandleCancelRequest(0x%x)" ), aFunction ) ); - - TUint16 operationToCancel( 0 ); - switch ( aFunction ) - { - - case EIscCancelAsyncInitialize: - { - if ( iDataTransmissionIniData ) - { - Kern::Free( iDataTransmissionBuffer ); - delete iDataTransmissionIniData; - iDataTransmissionIniData = NULL; - } - if ( iMultiplexerIniData ) - { - Kern::Free( iMultiplexerBuffer ); - delete iMultiplexerIniData; - iMultiplexerIniData = NULL; - } - - operationToCancel = EIscAsyncInitializeModemInterface; - break; - } - case EIscCancelAsyncOpen: - { - if ( KRequestPending == IsPending( EIscAsyncOpen ) ) - { - iChannelOpen = EFalse; - } - operationToCancel = EIscAsyncOpen; - break; - } - case EIscCancelAsyncSend: - { - operationToCancel = EIscAsyncSend; - // Cancel sending / empty send queues - iIscDevice->CancelSending( iChannelNumber, this ); - break; - } - case EIscCancelAsyncDataSend: - { - operationToCancel = EIscAsyncDataSend; - // Cancel sending / empty send queues - iIscDevice->CancelSending( iChannelNumber, this ); - break; - } - - case EIscCancelAsyncReceive: - { - iReceiveBufPtr = NULL; - iNeededBufLen = NULL; - operationToCancel = EIscAsyncReceive; - break; - } - - case EIscCancelAsyncDataReceive: - { - iDataReceiveBufPtr = NULL; - iNeededDataBufLen = NULL; - operationToCancel = EIscAsyncDataReceive; - break; - } - - case EIscCancelAsyncNotifyConnection: - { - iIscConnectionStatusPtr = NULL; - operationToCancel = EIscAsyncNotifyConnectionStatus; - break; - } - - case EIscCancelAsyncNotifyFlowControl: - { - iIscFlowControlStatusPtr = NULL; - operationToCancel = EIscAsyncNotifyFlowControlStatus; - break; - } - case EIscCancelAsyncCustomOperation1: - { - operationToCancel = EIscAsyncCustomOperation1; - break; - } - case EIscCancelAsyncCustomOperation2: - { - operationToCancel = EIscAsyncCustomOperation2; - break; - } - case EIscCancelAsyncCustomOperation3: - { - operationToCancel = EIscAsyncCustomOperation3; - break; - } - case EIscCancelAsyncCustomOperation4: - { - operationToCancel = EIscAsyncCustomOperation4; - break; - } - case EIscCancelAsyncCustomOperation5: - { - operationToCancel = EIscAsyncCustomOperation5; - break; - } - case EIscCancelAsyncClose: - { - TRACE_ASSERT_ALWAYS; - operationToCancel = EIscAsyncClose; - break; - } - default: - { - ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscUnknownCommand ); - break; - } - } - - iIscDevice->iIscMultiplexerInterface->CancelNotify( iChannelNumber, ( TUint16 )operationToCancel, this ); - CompleteRequest( operationToCancel, KErrCancel ); - - return KErrNone; - } - -// ----------------------------------------------------------------------------- -// DIscChannel::DoCreate -// Secondary initialization of channel -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -TInt DIscChannel::DoCreate( - TInt aUnit, - const TDesC8* anInfo, - const TVersion& /*aVer*/ ) - { - C_TRACE( ( _T( "DIscChannel::DoCreate(0x%x, 0x%x, 0x%x)" ), aUnit, anInfo, this ) ); - if ( !Kern::CurrentThreadHasCapability( ECapabilityCommDD,__PLATSEC_DIAGNOSTIC_STRING - ( "Checked by ISCDRIVER.LDD ( Inter-System Communication Driver )" ) ) ) - { - return KErrPermissionDenied; - } - TUint16 channelNumber = ( TUint16 )aUnit; - if ( anInfo ) - { - // check for channel number inside anInfo - TUint8 channel = ( TUint8 )( *anInfo )[0]; - if ( channel >= KIscMaxChannelsInLdd ) - { - channelNumber += KIscMaxChannelsInLdd; - } - C_TRACE( ( _T( "DIscChannel::DoCreate channel=0x%x" ), channelNumber ) ); - } - - if ( channelNumber != KIscControlChannel ) - { - TIscConfiguration config; - iIscDevice->iIscMultiplexerInterface->GetConfiguration( config ); - TInt i( KErrNone ); - iFrameRx = new TUint32*[config.channelRcvQueueSize]; - ASSERT_RESET_ALWAYS( iFrameRx, "IscDriver",EIscMemoryAllocationFailure ); - for ( i = KErrNone; i < config.channelRcvQueueSize; i++ ) - { - iFrameRx[i] = 0; - } - - iDataFrameRx = new TUint32*[config.channelDataRcvQueueSize]; - ASSERT_RESET_ALWAYS( iDataFrameRx, "IscDriver",EIscMemoryAllocationFailure ); - for ( i = KErrNone; i < config.channelDataRcvQueueSize; i++ ) - { - iDataFrameRx[i] = 0; - } - - // creating frame queue for incoming frames - iFrameRxQueue = new DIscQueue( iFrameRx, config.channelRcvQueueSize ); - ASSERT_RESET_ALWAYS( iFrameRxQueue, "IscDriver",EIscMemoryAllocationFailure ); - - // creating frame queue for incoming data frames - iDataFrameRxQueue = new DIscQueue( iDataFrameRx, config.channelDataRcvQueueSize ); - ASSERT_RESET_ALWAYS( iDataFrameRxQueue, "IscDriver",EIscMemoryAllocationFailure ); - - // Flowcontrol marks for data frames - iIscChannelHighWaterMark = ( TUint16 )( ( ( ( TUint16 )config.channelDataRcvQueueSize ) * KMultiplyByThree ) / KDivideByFour );// 75% = multiply with 3, divide by 4 - iIscChannelLowWaterMark = ( TUint16 )( ( ( ( TUint16 )config.channelDataRcvQueueSize ) * KMultiplyByOne ) / KDivideByFour );// 25% = multiply with 1, divide by 4 - - TRACE_ASSERT( iIscChannelHighWaterMark != 0 ); - } - -#ifndef ISC_CHANNEL_SHARING_IN_USE - // Remove checking if channel already set to enable channel sharing - //Check if channel already set - if ( IscChannelContainer::Channel( channelNumber, 0 ) ) - { - C_TRACE( ( _T( "DIscChannel::DoCreate channel 0x%x already set!!!!" ), channelNumber ) ); - return KErrAlreadyExists; - } -#endif //ISC_CHANNEL_SHARING_IN_USE - - //Add itself to channel table. - TInt error = IscChannelContainer::SetChannel( ( DIscChannel* )this, channelNumber ); - if ( KErrNone != error ) - { - return error; - } - - iChannelOpen = ETrue; - - // Store channel number. - iChannelNumber = channelNumber; - SetDfcQ( Kern::DfcQue0() ); - iMsgQ.Receive(); - - return KErrNone; - - } - - -// ----------------------------------------------------------------------------- -// DIscChannel::NotifyFlowControl -// Notify user side client that uplink flow control is on/off -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::NotifyFlowControl - ( - const TInt aFlowControlStatus - ) - { - C_TRACE( ( _T( "DIscChannel::NotifyFlowControl(0x%x) iChannelNumber 0x%x channelPtr 0x%x" ), aFlowControlStatus, iChannelNumber, this ) ); - - iULFlowControlStatus = aFlowControlStatus; - if( iIscRequests[ EIscAsyncNotifyFlowControlStatus ] - && iIscFlowControlStatusPtr ) - { - TPtr8 tempDes( reinterpret_cast( &iULFlowControlStatus ), sizeof ( TInt ), sizeof ( TInt ) ); - iLastNotifiedULFlowstatus = aFlowControlStatus; - TInt r = ThreadWrite( static_cast( iIscFlowControlStatusPtr ), &tempDes, 0 ); - TRACE_ASSERT( r == KErrNone ); - CompleteRequest( EIscAsyncNotifyFlowControlStatus, r ); - } - else - { - C_TRACE( ( _T( "DIscChannel::NotifyFlowControl No request pending!" ) ) ); - } - } - -// ----------------------------------------------------------------------------- -// DIscChannel::NotifyConnectionStatus -// Notify user side client that connection status has changed -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::NotifyConnectionStatus( - const TInt aConnectionStatus ) - { - C_TRACE( ( _T( "DIscChannel::NotifyConnectionStatus(0x%x) channelPtr 0x%x" ), aConnectionStatus, this ) ); - - if ( iIscRequests[EIscAsyncNotifyConnectionStatus] - && iIscConnectionStatusPtr ) - { - TInt temp = aConnectionStatus; - TPtr8 tempDes( ( TUint8* )&temp,sizeof ( TInt ),sizeof ( TInt ) ); - TInt r = ThreadWrite( ( TAny* )iIscConnectionStatusPtr, &tempDes, 0 ); - TRACE_ASSERT( r == KErrNone ); - - CompleteRequest( EIscAsyncNotifyConnectionStatus, r ); - } - } - -// ----------------------------------------------------------------------------- -// DIscChannel::IsPending -// Check if asynchronous request is active -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -TInt DIscChannel::IsPending( - const TUint16 aReqNumber ) - { - TInt error( KErrNone ); - if ( iIscRequests[aReqNumber] ) - { - error = KRequestPending; - } - else - { - // error is KErrNone - } - return error; - } -// ----------------------------------------------------------------------------- -// DIscChannel::CompleteRequest -// Function to complete clients pending asynchronous request -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::CompleteRequest( - TInt aOperation, - TInt aCompleteStatus ) - { - C_TRACE( ( _T( "DIscChannel::CompleteRequest(0x%x, 0x%x) iChannelNumber 0x%x channelPtr 0x%x" ), aOperation, aCompleteStatus, iChannelNumber, this ) ); - - if ( aOperation < EIscAsyncLast ) - { - - TRequestStatus* requestStatus = iIscRequests[aOperation]; - if ( requestStatus ) - { - // In case of higher priority thread, set request to NULL from the request table before actual completing - iIscRequests[aOperation] = NULL; - Kern::RequestComplete( iThread, requestStatus, aCompleteStatus ); - } - } - else - { - // Do nothing - } - - C_TRACE( ( _T( "DIscChannel::CompleteRequest - return void" ) ) ); - - } - -// ----------------------------------------------------------------------------- -// DIscChannel::InitializeComplete -// Initialization complete dfc -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::InitializeComplete( - TAny* aPtr ) - { - C_TRACE( ( _T( "DIscChannel::InitializeComplete(0x%x)" ), aPtr ) ); - - DIscChannel* ThisPtr = ( DIscChannel* )aPtr; - if ( KErrNone == ThisPtr->iDataTransmissionErrorCode ) - { - ThisPtr->DoMultiplexerInitialize(); - } - else - { - ThisPtr->CompleteRequest( EIscAsyncInitializeModemInterface, ThisPtr->iDataTransmissionErrorCode ); - } - C_TRACE( ( _T( "DIscChannel::InitializeComplete - return 0x%x" ) ) ); - - } - -// ----------------------------------------------------------------------------- -// DIscChannel::DoMultiplexerInitialize -// Completes the multiplexer initialization -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::DoMultiplexerInitialize() - { - C_TRACE( ( _T( "DIscChannel::DoMultiplexerInitialize() channelPtr 0x%x" ), this ) ); - - if ( iIscRequests[EIscAsyncInitializeModemInterface] ) - { - - iIscDevice->iIscMultiplexerInterface->InitializeMultiplexer( - EIscAsyncInitializeModemInterface, - *iMultiplexerIniData, - this ); - } - - C_TRACE( ( _T( "DIscChannel::DoMultiplexerInitialize - return void" ) ) ); - } - -// ----------------------------------------------------------------------------- -// DIscChannel::StoreFrame -// Stores the incoming frame to channels receive queue -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::StoreFrame( TDesC8* aData ) - { - C_TRACE( ( _T( "DIscChannel::StoreFrame(0x%x) channelId 0x%x channelPtr 0x%x" ), aData, iChannelNumber, this ) ); - - TInt error( KErrNone ); - - TIscFrameInfo frameInfo; - iIscDevice->iIscMultiplexerInterface->GetFrameInfo( *aData, frameInfo ); - - if ( frameInfo.frameType == EIscDataFrame ) - { - C_TRACE( ( _T( "DIscChannel::StoreFrame dataFrame" ) ) ); - error = iDataFrameRxQueue->Add( ( TAny* )aData ); - if ( error == KErrNone ) - { - if ( iDataFrameRxQueue->Count() >= iIscChannelHighWaterMark - && iDLFlowControlStatus == EIscFlowControlOff ) - { - iIscDevice->DLFlowControlNotify( EIscFlowControlOn, iChannelNumber, this ); - iDLFlowControlStatus = EIscFlowControlOn; - } - else if ( iDataFrameRxQueue->Count() <= iIscChannelLowWaterMark - && iDLFlowControlStatus != EIscFlowControlOff ) - { - iIscDevice->DLFlowControlNotify( EIscFlowControlOff, iChannelNumber, this ); - iDLFlowControlStatus = EIscFlowControlOff; - } - else - { - // Do nothing - } - } - else - { - // Set overflow flag on. Complete next DataReceive with KErrOverFlow - TRACE_ASSERT_ALWAYS; - iOverFlow = ETrue; - iIscDevice->ReleaseMemoryBlock( ( TDes8* )aData ); - } - } - - else - { - C_TRACE( ( _T( "DIscChannel::StoreFrame controlFrame" ) ) ); - error = iFrameRxQueue->Add( ( TAny* )aData ); - if ( error != KErrNone ) - { - C_TRACE( ( _T( "DIscChannel::StoreFrame() CONTROL FRAME OVERFLOW channel %d" ), iChannelNumber ) ); - TRACE_ASSERT_ALWAYS; - iClientPanic = ETrue; - iIscDevice->ReleaseMemoryBlock( ( TDes8* )aData ); - } - } - - C_TRACE( ( _T( "DIscChannel::StoreFrame - return void" ) ) ); - } - -// ----------------------------------------------------------------------------- -// DIscChannel::EmptyBuffers -// Goes through channel's queue and delivers possible frame( s ) to client -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::EmptyBuffers() - { - C_TRACE( ( _T( "DIscChannel::EmptyBuffers() channelId 0x%x channelPtr 0x%x" ),iChannelNumber, this ) ); - - if ( iDataFrameRxQueue->NextBufferLength() > KErrNone ) - { - TDes8* tempPtr = ( TDes8* ) iDataFrameRxQueue->GetFirst(); - TIscFrameInfo frameInfo; - TInt desMaxLen( KErrNone ); - - iIscDevice->iIscMultiplexerInterface->GetFrameInfo( *tempPtr, frameInfo ); - - // frame incoming, and datareceive request active - if ( iIscRequests[EIscAsyncDataReceive] && frameInfo.frameType == EIscDataFrame ) - { - if ( frameInfo.concatenation == EIscNoConcatenation ) - { - desMaxLen = Kern::ThreadGetDesMaxLength( iThread, iDataReceiveBufPtr ); - - C_TRACE( ( _T( "DIscChannel::EmptyBuffers() data desMaxLen %d" ),desMaxLen ) ); - - TRACE_ASSERT( desMaxLen > KErrNone ); - - // check that client's memory block is big enough - if ( desMaxLen >= frameInfo.writeLength ) - { - // create a temporary descriptor for writing since we're - // necessary not writing the whole contents of the - // source descriptor, only the part that ISC Multiplexer - // wants - TPtr8 writePtr( ( TUint8* )( tempPtr->Ptr() + frameInfo.writeStartIndex ), - frameInfo.writeLength, - frameInfo.writeLength ); - - TInt r = ThreadWrite( iDataReceiveBufPtr, &writePtr, 0 ); - - TRACE_ASSERT( r == KErrNone ); - - // remove the pointer from queue and release the memory block - // but only if the ThreadWrite was successfull - if ( r == KErrNone ) - { - iDataFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( tempPtr ); - if ( iOverFlow ) - { - iOverFlow = EFalse; - CompleteRequest( EIscAsyncDataReceive, KErrOverflow ); - } - else - { - CompleteRequest( EIscAsyncDataReceive, KErrNone ); - } - } - else - { - C_TRACE( ( _T( "DIscChannel::EmptyBuffers() data ThreadWrite %d" ), r ) ); - CompleteRequest( EIscAsyncDataReceive, r ); - } - } - // client buffer too small - else - { - TUint16 tempLen( frameInfo.writeLength ); - TPtr8 tempLenDes( ( TUint8* )&tempLen, sizeof ( TUint16 ), sizeof ( TUint16 ) ); - - TInt r = ThreadWrite( ( TAny* )iNeededDataBufLen, &tempLenDes, 0 ); - TRACE_ASSERT( r == KErrNone ); - if ( r != KErrNone ) - { - C_TRACE( ( _T( "DIscChannel::EmptyBuffers() data ThreadWrite %d" ), r ) ); - } - - CompleteRequest( EIscAsyncDataReceive, KErrNoMemory ); - } - } - else - { - HandleConcatenatedDataFrame( tempPtr, frameInfo ); - } - } - } - // no frames in data queue - else - { - C_TRACE( ( _T( "DIscChannel::EmptyBuffers() channelId 0x%x channelPtr No frames in data queue" ), iChannelNumber, this ) ); - } - - // Check if there is frame in queue - if ( iFrameRxQueue->NextBufferLength() > KErrNone ) - { - TDes8* tempPtr = ( TDes8* ) iFrameRxQueue->GetFirst(); - TIscFrameInfo frameInfo; - TInt desMaxLen( KErrNone ); - - iIscDevice->iIscMultiplexerInterface->GetFrameInfo( *tempPtr, frameInfo ); - - // frame incoming and normal receive request active - if ( iIscRequests[EIscAsyncReceive] && frameInfo.frameType == EIscNonDataFrame ) - { - if ( frameInfo.concatenation == EIscNoConcatenation ) - { - desMaxLen = Kern::ThreadGetDesMaxLength( iThread, iReceiveBufPtr ); - - C_TRACE( ( _T( "DIscChannel::EmptyBuffers() desMaxLen %d" ),desMaxLen ) ); - - TRACE_ASSERT( desMaxLen > KErrNone ); - - // check that client's memory block is big enough - if ( desMaxLen >= frameInfo.writeLength ) - { - // create a temporary descriptor for writing since we're - // necessary not writing the whole contents of the - // source descriptor, only the part that ISC Multiplexer - // wants - TPtr8 writePtr( ( TUint8* )( tempPtr->Ptr() + frameInfo.writeStartIndex ), - frameInfo.writeLength, - frameInfo.writeLength ); - - TInt r = ThreadWrite( iReceiveBufPtr, &writePtr, 0 ); - - TRACE_ASSERT( r == KErrNone ); - - // remove the pointer from queue and release the memory block - // but only if the ThreadWrite was successfull - if ( r == KErrNone ) - { - iFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( tempPtr ); - if ( iClientPanic ) - { - iClientPanic = EFalse; - CompleteRequest( EIscAsyncReceive, KErrOverflow ); - } - else - { - CompleteRequest( EIscAsyncReceive, KErrNone ); - } - } - else - { - C_TRACE( ( _T( "DIscChannel::EmptyBuffers() ThreadWrite %d" ), r ) ); - CompleteRequest( EIscAsyncReceive, r ); - } - } - // client buffer too small - else - { - TUint16 tempLen = frameInfo.writeLength; - TPtr8 tempLenDes( ( TUint8* )&tempLen, sizeof ( TUint16 ), sizeof ( TUint16 ) ); - - TInt r = ThreadWrite ( ( TAny* )iNeededBufLen, &tempLenDes, 0 ); - TRACE_ASSERT( r == KErrNone ); - if ( r != KErrNone ) - { - C_TRACE( ( _T( "DIscChannel::EmptyBuffers() ThreadWrite %d" ), r ) ); - } - - CompleteRequest( EIscAsyncReceive, KErrNoMemory ); - } - } - else - { - HandleConcatenatedFrame( tempPtr, frameInfo ); - } - } - } - // no frames in queue - else - { - C_TRACE( ( _T( "DIscChannel::EmptyBuffers() channelId 0x%x channelPtr 0x%x No frames in queue" ), iChannelNumber, this ) ); - } - - // If possible, set flow control off from data frame receiving - if ( iDataFrameRxQueue->Count() <= iIscChannelLowWaterMark - && iDLFlowControlStatus != EIscFlowControlOff ) - { - iIscDevice->DLFlowControlNotify( EIscFlowControlOff, iChannelNumber, this ); - iDLFlowControlStatus = EIscFlowControlOff; - } - - - C_TRACE( ( _T( "DIscChannel::EmptyBuffers - return void" ) ) ); - - } - -// ----------------------------------------------------------------------------- -// DIscChannel::HandleConcatenatedDataFrame -// Copies several data frames to clients buffer if needed before compliting receive request -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::HandleConcatenatedDataFrame( TDes8* aPtr, TIscFrameInfo& aInfo ) - { - C_TRACE( ( _T( "DIscChannel::HandleConcatenatedDataFrame(0x%x, 0x%x) channelPtr 0x%x" ), aPtr, &aInfo, this ) ); - TInt desMaxLen( KErrNone ); - TInt desLen( KErrNone ); - TUint16 totalLength( 0 ); - - desMaxLen = Kern::ThreadGetDesMaxLength( iThread, iDataReceiveBufPtr ); - desLen = Kern::ThreadGetDesLength( iThread, iDataReceiveBufPtr ); - - if ( aInfo.totalLength > KErrNone ) - { - totalLength = aInfo.totalLength; - } - else - { - totalLength = desMaxLen; - } - switch ( aInfo.concatenation ) - { - // first frame of a larger data chunk - case EIscConcatenationDataStart: - { - // check whether the whole data amount will fit into the user buffer - if ( desMaxLen >= ( desLen + aInfo.writeLength ) && desMaxLen >= totalLength ) - { - // create a temporary descriptor for writing since we're - // necessary not writing the whole contents of the - // source descriptor, only the part that ISC Multiplexer - // wants - TPtr8 writePtr( ( TUint8* )( aPtr->Ptr() + aInfo.writeStartIndex ), - aInfo.writeLength, - aInfo.writeLength ); - - // start writing the data at offset 0 since this is the first frame - TInt r = ThreadWrite( iDataReceiveBufPtr, &writePtr, 0 ); - - // remove the pointer from queue and release the memory block - // but only if the ThreadWrite was successfull - // we do not complete the user request until EIscConcatenationDataEnd - if ( r == KErrNone ) - { - iDataFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( aPtr ); - } - else - { - C_TRACE( ( _T( "DIscChannel::HandleConcatenatedDataFrame() ThreadWrite %d" ), r ) ); - TRACE_ASSERT_ALWAYS; - CompleteRequest( EIscAsyncDataReceive, KErrWrite ); - } - } - else // buffer too small - { - TRACE_ASSERT( totalLength >= ( desLen + aInfo.writeLength ) ); - TPtr8 tempLenDes( ( TUint8* )&totalLength, sizeof ( TUint16 ), sizeof ( TUint16 ) ); - TInt r = ThreadWrite ( ( TAny* )iNeededDataBufLen, &tempLenDes, 0 ); - TRACE_ASSERT( r == KErrNone ); - if ( r != KErrNone ) - { - C_TRACE( ( _T( "DIscChannel::HandleConcatenatedDataFrame() data start KErrNoMemory ThreadWrite %d" ), r ) ); - } - - CompleteRequest( EIscAsyncDataReceive, KErrNoMemory ); - } - break; - } - case EIscConcatenationData: - case EIscConcatenationDataEnd: - { - // check whether the next frame fits to the remaining buffer - if ( ( desMaxLen - desLen ) >= aInfo.writeLength ) - { - // create a temporary descriptor for writing since we're - // necessary not writing the whole contents of the - // source descriptor, only the part that ISC Multiplexer - // wants - TPtr8 writePtr( ( TUint8* )( aPtr->Ptr() + aInfo.writeStartIndex ), - aInfo.writeLength, - aInfo.writeLength ); - - // start writing the data at offset desLen - TInt r = ThreadWrite( iDataReceiveBufPtr, &writePtr, desLen ); - TRACE_ASSERT( r == KErrNone ); - // remove the pointer from queue and release the memory block - // but only if the ThreadWrite was successfull - if ( r == KErrNone ) - { - iDataFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( aPtr ); - } - else - { - C_TRACE( ( _T( "DIscChannel::HandleConcatenatedDataFrame() data ThreadWrite %d" ), r ) ); - } - - // complete client request if the frame was the last one - if ( aInfo.concatenation == EIscConcatenationDataEnd ) - { - if ( r == KErrNone ) - { - CompleteRequest( EIscAsyncDataReceive, KErrNone ); - } - else - { - CompleteRequest( EIscAsyncDataReceive, KErrWrite ); - } - } - } - else - { - CompleteRequest( EIscAsyncDataReceive, KErrUnderflow ); - } - break; - } - default: - { - ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscNotAllowedCallToDoCancel ); - break; - } - } - } - -// ----------------------------------------------------------------------------- -// DIscChannel::HandleConcatenatedFrame -// Copies several frames to clients buffer if needed before compliting receive request -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::HandleConcatenatedFrame( TDes8* aPtr, TIscFrameInfo& aInfo ) - { - C_TRACE( ( _T( "DIscChannel::HandleConcatenatedFrame(0x%x, 0x%x) channelPtr 0x%x" ), aPtr, &aInfo, this ) ); - TInt desMaxLen( 0 ); - TInt desLen( 0 ); - TUint16 totalLength( 0 ); - - desMaxLen = Kern::ThreadGetDesMaxLength( iThread, iReceiveBufPtr ); - desLen = Kern::ThreadGetDesLength( iThread, iReceiveBufPtr ); - - if ( aInfo.totalLength > 0 ) - { - totalLength = aInfo.totalLength; - } - else - { - totalLength = desMaxLen; - } - switch ( aInfo.concatenation ) - { - // first frame of a larger data chunk - case EIscConcatenationDataStart: - { - // check whether the whole data amount will fit into the user buffer - if ( desMaxLen >= ( desLen + aInfo.writeLength ) && desMaxLen >= totalLength ) - { - // create a temporary descriptor for writing since we're - // necessary not writing the whole contents of the - // source descriptor, only the part that ISC Multiplexer - // wants - TPtr8 writePtr( ( TUint8* )( aPtr->Ptr() + aInfo.writeStartIndex ), - aInfo.writeLength, - aInfo.writeLength ); - - // start writing the data at offset 0 since this is the first frame - TInt r = ThreadWrite( iReceiveBufPtr, &writePtr, 0 ); - TRACE_ASSERT( r == KErrNone ); - - // remove the pointer from queue and release the memory block - // but only if the ThreadWrite was successfull - // we do not complete the user request until EIscConcatenationDataEnd - if ( r == KErrNone ) - { - iFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( aPtr ); - } - else - { - C_TRACE( ( _T( "DIscChannel::HandleConcatenatedFrame() ThreadWrite %d" ), r ) ); - CompleteRequest( EIscAsyncReceive, KErrWrite ); - } - } - else // buffer too small - { - TRACE_ASSERT( totalLength >= ( desLen + aInfo.writeLength ) ); - TPtr8 tempLenDes( ( TUint8* )&totalLength, sizeof ( TUint16 ), sizeof ( TUint16 ) ); - TInt r = ThreadWrite ( ( TAny* )iNeededBufLen, &tempLenDes, 0 ); - TRACE_ASSERT( r == KErrNone ); - if ( r != KErrNone ) - { - C_TRACE( ( _T( "DIscChannel::HandleConcatenatedFrame() ThreadWrite %d" ), r ) ); - } - - CompleteRequest( EIscAsyncReceive, KErrNoMemory ); - } - break; - } - case EIscConcatenationData: - case EIscConcatenationDataEnd: - { - // check whether the next frame fits to the remaining buffer - if ( ( desMaxLen - desLen ) >= aInfo.writeLength ) - { - // create a temporary descriptor for writing since we're - // necessary not writing the whole contents of the - // source descriptor, only the part that ISC Multiplexer - // wants - TPtr8 writePtr( ( TUint8* )( aPtr->Ptr() + aInfo.writeStartIndex ), - aInfo.writeLength, - aInfo.writeLength ); - - // start writing the data at offset desLen - TInt r = ThreadWrite( iReceiveBufPtr, &writePtr, desLen ); - - if ( r != KErrNone ) - { - C_TRACE( ( _T( "DIscChannel::HandleConcatenatedFrame() ThreadWrite %d" ), r ) ); - } - // remove the pointer from queue and release the memory block - // but only if the ThreadWrite was successfull - if ( r == KErrNone ) - { - iFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( aPtr ); - } - - // complete client request if the frame was the last one - if ( aInfo.concatenation == EIscConcatenationDataEnd ) - { - if ( r == KErrNone ) - { - CompleteRequest( EIscAsyncReceive, KErrNone ); - } - else - { - CompleteRequest( EIscAsyncReceive, KErrWrite ); - } - } - } - else - { - CompleteRequest( EIscAsyncDataReceive, KErrUnderflow ); - } - break; - } - default: - { - ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscUnknownCommand ); - break; - } - } - - } - -// ----------------------------------------------------------------------------- -// DIscChannel::CopyFromUserBuffer -// Copy data from user-thread memory space. -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -TInt DIscChannel::CopyFromUserBuffer( - const TDesC8& aUserBuffer, - TDes8& aKernelBuffer, - const TInt aOffset ) - { - C_TRACE( ( _T( "DIscChannel::CopyFromUserBuffer(0x%x, 0x%x, 0x%x) channelPtr 0x%x" ), &aUserBuffer, &aKernelBuffer, aOffset, this ) ); - return Kern::ThreadDesRead( iThread, ( TAny* )&aUserBuffer, aKernelBuffer, aOffset, KChunkShiftBy0 ); - - } - -// ----------------------------------------------------------------------------- -// DIscChannel::ThreadWrite -// Writes data/frames to clients buffer -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -TInt DIscChannel::ThreadWrite( - TAny* dest, - const TDesC8* src, - const TInt aOffset ) - { - C_TRACE( ( _T( "DIscChannel::ThreadWrite(0x%x, 0x%x, 0x%x)" ), dest, src, aOffset ) ); - C_TRACE( ( _T( "DIscChannel::ThreadWrite writeLen 0x%x" ), src->Length() ) ); - - return Kern::ThreadDesWrite( iThread, dest, *src, aOffset, iThread ); - - } - -// ----------------------------------------------------------------------------- -// DIscChannel::ResetBuffers -// Resets buffers -// ( other items were commented in a header ). -// ----------------------------------------------------------------------------- -// -void DIscChannel::ResetBuffers() - { - // Delete pending send frames - iIscDevice->CancelSending( iChannelNumber, this ); - - // Empty receive queue - if ( iFrameRxQueue ) - { - while ( !iFrameRxQueue->Empty() ) - { - TDes8* tempPtr = ( TDes8* ) iFrameRxQueue->GetFirst(); - iFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( tempPtr ); - } - } - - // Empty data receive queue - if ( iDataFrameRxQueue ) - { - while ( !iDataFrameRxQueue->Empty() ) - { - TDes8* tempPtr = ( TDes8* ) iDataFrameRxQueue->GetFirst(); - iDataFrameRxQueue->DeleteFirst(); - iIscDevice->ReleaseMemoryBlock( tempPtr ); - } - } - } - -// End of File