--- a/systemswstubs/examplecommonisc/IscDriver/src/IscChannel.cpp Tue Sep 07 08:19:48 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 <kern_priv.h>
-#include <IscDataTransmissionBase.h>
-#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<TPtr8*>( tablePtr[ KSecondParam ] );
- iIscRequests[ EIscAsyncNotifyFlowControlStatus ] = reinterpret_cast<TRequestStatus*>( 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<TUint8*>( &iULFlowControlStatus ), sizeof ( TInt ), sizeof ( TInt ) );
- iLastNotifiedULFlowstatus = aFlowControlStatus;
- TInt r = ThreadWrite( static_cast<TAny*>( 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