diff -r e71858845f73 -r e1758cbb96ac systemswstubs/examplecommonisc/IscDriver/src/IscDevice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/systemswstubs/examplecommonisc/IscDriver/src/IscDevice.cpp Mon Oct 04 00:04:35 2010 +0300 @@ -0,0 +1,927 @@ +/* +* 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 +#include + +#include "IscMainRcvBuffer.h" +#include "IscQueue.h" +#include "IscSendQueue.h" +#include "IscDevice.h" +#include "IscChannel.h" +#include "IscChannelContainer.h" +#include "IscTrace.h" + +#ifdef __WINS__ +#include +#endif + + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +_LIT( KIscDriverName, "IscDriver" ); + +// MACROS + +// LOCAL CONSTANTS AND MACROS +const TInt KSendDfcPriority( 4 ); +const TInt KNotifyDfcPriority( 5 ); +const TInt KIscInterruptLevelTwo( 2 ); + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + + +DIscDataTransmissionBase* DIscDevice::iIscDataTransmissionInterface = NULL; +DIscMultiplexerBase* DIscDevice::iIscMultiplexerInterface = NULL; +DIscSendQueue* DIscDevice::iSendQueue=NULL; +DIscSendQueue* DIscDevice::iTempQueue=NULL; +DIscSendQueue* DIscDevice::iControlSendQueue=NULL; +TDfc* DIscDevice::iSendDfc = NULL; +TDfc* DIscDevice::iNotifyDfc = NULL; +TInt DIscDevice::iConnectionStatus = EIscConnectionNotOk; + +#ifdef __WINS__ +CRITICAL_SECTION g_IscDTBCriticalSection; +#endif + +// ============================ MEMBER FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// DIscDevice::DIscDevice +// C++ default constructor +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C DIscDevice::DIscDevice() + :DLogicalDevice(), + iSend( NULL ), + iTempSend( NULL ), + iControlSend( NULL ), + iSendFrameParameters( NULL ), + iTempFrameParameters( NULL ), + iControlFrameParameters( NULL ), + iIscMainRcvBuffer( NULL ) + { + C_TRACE( ( _T( "DIscDevice::DIscDevice()" ) ) ); + + iVersion = TVersion( KMajorVersionNumber, KMinorVersionNumber, + KBuildVersionNumber ); + iParseMask |= KDeviceAllowUnit; + iParseMask |= KDeviceAllowInfo; + +#ifdef __WINS__ + InitializeCriticalSection( &g_IscDTBCriticalSection ); +#endif + } + +// Destructor +EXPORT_C DIscDevice::~DIscDevice() + { + C_TRACE( ( _T( "DIscDevice::~DIscDevice()" ) ) ); + + IscChannelContainer::DeActivate(); + + if ( iIscMainRcvBuffer ) + { + delete iIscMainRcvBuffer; + iIscMainRcvBuffer = NULL; + } + + + iIscDataTransmissionInterface = NULL; + iIscMultiplexerInterface = NULL; + + delete iTempSend; + delete iControlSend; + delete iSendQueue; + delete iTempQueue; + delete iControlSendQueue; + delete iSendDfc; + delete iNotifyDfc; + +#ifdef __WINS__ + DeleteCriticalSection( &g_IscDTBCriticalSection ); +#endif + + } + + +// ----------------------------------------------------------------------------- +// DIscDevice::Install +// Complete the installation of driver +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +TInt DIscDevice::Install() + { + C_TRACE( ( _T( "DIscDevice::Install()" ) ) ); + + // Dfc for sending frames + iSendDfc = new TDfc( Flush, this, Kern::DfcQue0(), KSendDfcPriority ); + iNotifyDfc = new TDfc( NotifyConnection, this, Kern::DfcQue0(), KNotifyDfcPriority ); + ASSERT_RESET_ALWAYS( iSendDfc, "IscDriver",EIscMemoryAllocationFailure ); + + //Initialize IscChannelContainer + IscChannelContainer::Initialize(); + + // connect to multiplexer and data transmission driver + TInt r = InitializeLdd2LddInterface(); + if ( r != KErrNone ) + { + TRACE_ASSERT_ALWAYS; + return r; + } + + return ( SetName( &KIscDriverName ) ); + } + +// ----------------------------------------------------------------------------- +// DIscDevice::Initialize +// Complete the initialization of driver +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +void DIscDevice::Initialize() + { + C_TRACE( ( _T( "DIscDevice::Initialize()" ) ) ); + + TInt i( 0 ); + + // Get buffer configuration data from multiplexer + TIscConfiguration configData; + iIscMultiplexerInterface->GetConfiguration( configData ); + + // Create main buffer + iIscMainRcvBuffer = new DIscMainRcvBuffer( this, configData.mainRcvQueueSize ); + ASSERT_RESET_ALWAYS( iIscMainRcvBuffer, "IscDriver",EIscMemoryAllocationFailure ); + + // Do second phase installation + iIscMainRcvBuffer->DoCreate(); + + // Create queue for sending frames + iSend = new TUint32*[configData.channelSendQueueSize]; + ASSERT_RESET_ALWAYS( iSend, "IscDriver",EIscMemoryAllocationFailure ); + + iSendFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize]; + for ( i = 0; i < configData.channelSendQueueSize; i++ ) + { + iSendFrameParameters[i] = new TIscSendFrameInfo; + } + ASSERT_RESET_ALWAYS( iSendFrameParameters, "IscDriver",EIscMemoryAllocationFailure ); + + iSendQueue = new DIscSendQueue( iSend, iSendFrameParameters, configData.channelSendQueueSize ); + ASSERT_RESET_ALWAYS( iSendQueue, "IscDriver",EIscMemoryAllocationFailure ); + + + // create temporary queue + iTempSend = new TUint32*[configData.channelSendQueueSize]; + ASSERT_RESET_ALWAYS( iTempSend, "IscDriver",EIscMemoryAllocationFailure ); + + iTempFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize]; + for ( i =0; i < configData.channelSendQueueSize; i++ ) + { + iTempFrameParameters[i] = new TIscSendFrameInfo; + } + ASSERT_RESET_ALWAYS( iTempFrameParameters, "IscDriver",EIscMemoryAllocationFailure ); + + iTempQueue = new DIscSendQueue( iTempSend, iTempFrameParameters, configData.channelSendQueueSize ); + ASSERT_RESET_ALWAYS( iTempQueue, "IscDriver",EIscMemoryAllocationFailure ); + + + // Create send queue for control channel + iControlSend = new TUint32*[configData.channelSendQueueSize]; + ASSERT_RESET_ALWAYS( iControlSend, "IscDriver",EIscMemoryAllocationFailure ); + + iControlFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize]; + for ( i = 0; i < configData.channelSendQueueSize; i++ ) + { + iControlFrameParameters[i] = new TIscSendFrameInfo; + } + ASSERT_RESET_ALWAYS( iControlFrameParameters, "IscDriver",EIscMemoryAllocationFailure ); + + iControlSendQueue = new DIscSendQueue( iControlSend, iControlFrameParameters, configData.channelSendQueueSize ); + ASSERT_RESET_ALWAYS( iControlSendQueue, "IscDriver",EIscMemoryAllocationFailure ); + + iIscDataTransmissionInterface->AllocBuffers( configData.bufferConfig ); + + iConnectionStatus = iIscDataTransmissionInterface->ConnectionStatus(); + + iIscMultiplexerInterface->NotifyConnectionStatus( iConnectionStatus ); + C_TRACE( ( _T( "DIscDevice::Initialize - return void" ) ) ); + } +// ----------------------------------------------------------------------------- +// DIscDevice::GetCaps +// +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C void DIscDevice::GetCaps( + TDes8& /*aDes*/ ) const + { + // GetCaps implemented to keep compiler happy + } + +// ----------------------------------------------------------------------------- +// DEcsDevice::Create +// From DLogicalDevice +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +TInt DIscDevice::Create( + DLogicalChannelBase*& aChannel ) + { + aChannel=new DIscChannel( this ); + return aChannel?KErrNone:KErrNoMemory; + } + +// ----------------------------------------------------------------------------- +// DIscDevice::Receive +// Frames coming from Domestic OS +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C void DIscDevice::Receive( + TDesC8* aData ) const + { + DIscMainRcvBuffer::MsgReceive( aData ); + } + + +// ----------------------------------------------------------------------------- +// DIscDevice::ReserveMemoryBlock +// Get message block from buffers allocated in IscDataTransmissionBase.dll +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C void DIscDevice::ReserveMemoryBlock( TDes8*& aPtr, TUint16 aSize ) + { + iIscDataTransmissionInterface->ReserveMemoryBlock( aPtr, aSize ); + } + +// ----------------------------------------------------------------------------- +// DIscDevice::ReleaseMemoryBlock +// Release memory block allocated with ReserveMemoryBlock +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C void DIscDevice::ReleaseMemoryBlock( + TDes8* aPtr ) + { + C_TRACE( ( _T( "DIscDevice::ReleaseMemoryBlock(0x%x)" ), aPtr ) ); + + if ( iIscDataTransmissionInterface ) + { + iIscDataTransmissionInterface->ReleaseMemoryBlock( aPtr ); + } + } + +// ----------------------------------------------------------------------------- +// DIscDevice::NotifyConnectionStatus +// Connection status change function +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C void DIscDevice::NotifyConnectionStatus( const TInt aStatus ) + { + C_TRACE( ( _T( "DIscDevice::NotifyConnectionStatus(0x%x)" ), aStatus ) ); + if ( iConnectionStatus != aStatus ) + { + iConnectionStatus = aStatus; + if ( NKern::CurrentContext() == NKern::EInterrupt ) + { + iNotifyDfc->Add(); + } + else + { + iNotifyDfc->Enque(); + } + } + + C_TRACE( ( _T( "DIscDevice::NotifyConnectionStatus() return" ) ) ); + } + +// ----------------------------------------------------------------------------- +// DIscDevice::NotifyConnection +// Connection status change DFC function. +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +void DIscDevice::NotifyConnection( TAny* ) + { + C_TRACE( ( _T( "DIscDevice::NotifyConnection(0x%x)" ), iConnectionStatus ) ); + + iIscMultiplexerInterface->NotifyConnectionStatus( iConnectionStatus ); + DIscChannel* tempPtr = NULL; + for ( TUint16 i = KIscFirstChannel; i < KIscNumberOfUnits; i++ ) + { + for ( TUint16 ii( 0 ); ii < KIscMaxNumberOfChannelSharers; ii++ ) + { + tempPtr = IscChannelContainer::Channel( i, ii ); + if ( tempPtr ) + { + tempPtr->NotifyConnectionStatus( iConnectionStatus ); + tempPtr = NULL; + } + } + } + C_TRACE( ( _T( "DIscDevice::NotifyConnection() return" ) ) ); + + } + +// ----------------------------------------------------------------------------- +// DIscDevice::ULFlowControl +// Function to notify client about uplink flow control status +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C void DIscDevice::ULFlowControl( + const TInt aULFlowStatus, + const TUint16 aChannelId, + const TAny* aChannelPtr ) + { + C_TRACE( ( _T( "DIscDevice::ULFlowControl(0x%x, 0x%x, 0x%x)" ), aULFlowStatus, aChannelId, aChannelPtr ) ); + + DIscChannel* tempPtr = NULL; + TBool channelFound(EFalse); + + if ( !aChannelPtr ) + { + // All channels. + for ( TUint16 i(0); i < KIscMaxNumberOfChannelSharers; i++ ) + { + tempPtr = IscChannelContainer::Channel( aChannelId, i ); + if ( tempPtr ) + { + tempPtr->NotifyFlowControl( aULFlowStatus ); + tempPtr = NULL; + channelFound = ETrue; + } + else + { + //Do nothing + } + } + } + else + { + // Single channel. + for ( TUint16 i(0); i < KIscMaxNumberOfChannelSharers; i++ ) + { + tempPtr = IscChannelContainer::Channel( aChannelId, i ); + if ( tempPtr == ( DIscChannel* )aChannelPtr ) + { + tempPtr->NotifyFlowControl( aULFlowStatus ); + tempPtr = NULL; + channelFound = ETrue; + break; + } + else + { + //Do nothing + } + } + } + + if ( channelFound == EFalse ) + TRACE_ASSERT_ALWAYS; + + } + +// ----------------------------------------------------------------------------- +// DIscDevice::IsPending +// Function to check if asycnhronous request is active +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt DIscDevice::IsPending( + const TUint16 aReqNumber, + const TAny* aChannelPtr ) + { + C_TRACE( ( _T( "DIscDevice::IsPending(0x%x, 0x%x)" ), aReqNumber, aChannelPtr ) ); + + DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; + TInt error = IscChannelContainer::ValidateChannel( tempPtr ); + if( error == KErrNone ) + { + error = tempPtr->IsPending( aReqNumber ); + } + C_TRACE( ( _T( "DIscDevice::IsPending - return %d" ), error ) ); + return error; + + } + +// ----------------------------------------------------------------------------- +// DIscDevice::DLFlowControl +// Notify multiplexer about down link flow control +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +void DIscDevice::DLFlowControlNotify( + const TInt aDLFlowStatus, + const TUint16 aChannel, + const TAny* aChannelPtr ) + { + C_TRACE( ( _T( "DIscDevice::DLFlowControlNotify(0x%x, 0x%x)" ), aDLFlowStatus, aChannel ) ); + if ( aChannel >= KIscFirstChannel + && aChannel < KIscNumberOfUnits ) + { + if ( aDLFlowStatus == EIscFlowControlOn ) + { + iIscMultiplexerInterface->DLFlowControl( EIscFlowControlOn, aChannel, aChannelPtr ); + } + else + { + iIscMultiplexerInterface->DLFlowControl( EIscFlowControlOff, aChannel, aChannelPtr ); + } + } + else + { + + if ( aChannel == 0x00 ) + { + // control channel, no flow control used + } + else + { + // should never came here + TRACE_ASSERT_ALWAYS; + } + } + } + +// ----------------------------------------------------------------------------- +// DIscDevice::InitializeLdd2LddInterface +// Function to connect to DataTransmission and Multiplexer ldds +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +TInt DIscDevice::InitializeLdd2LddInterface() + { + C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface()" ) ) ); + + // Find pointer to second level LDD. + DObjectCon* lDevices = Kern::Containers()[ ELogicalDevice ]; + TKName driverName; + ASSERT_RESET_ALWAYS( lDevices, "IscDriver", EIscLogicalDevicesNotFound ); + + TInt err( KErrNone ); + //TInt driverHandle( KErrNone ); // API change in SOS9.2 WK08 + TFindHandle driverHandle; + // Find pointer to ISC Multiplexer. + err = lDevices->FindByName( driverHandle, KIscMultiplexerName, driverName ); + if( KErrNone != err ) + { + C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface() ISC Multiplexer Not Found!" ) ) ); + ASSERT_RESET_ALWAYS( 0, "IscDriver" ,EIscMultiplexerNotFound ); + } + + iIscMultiplexerInterface = static_cast( lDevices->At( driverHandle ) ); + ASSERT_RESET_ALWAYS( iIscMultiplexerInterface, "IscDriver", EIscMultiplexerNotFound ); + + //TInt secondDriverHandle( KErrNone ); // API change in SOS9.2 WK08 + TFindHandle secondDriverHandle; + // Find pointer to Data Transmission Plugin. + err = lDevices->FindByName( secondDriverHandle, KIscDataTransmissionDriverName, driverName ); + if( KErrNone != err ) + { + C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface() Data Transmission Plug-In Not Found!" ) ) ); + ASSERT_RESET_ALWAYS( 0, "IscDriver", EIscDataTransmissionDriverNotFound ); + } + + iIscDataTransmissionInterface = static_cast( lDevices->At( secondDriverHandle ) ); + ASSERT_RESET_ALWAYS( iIscDataTransmissionInterface, "IscDriver", EIscDataTransmissionDriverNotFound ); + + iIscDataTransmissionInterface->Connect( this ); + iIscMultiplexerInterface->Connect( this ); + + C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface - return 0x%x" ), err ) ); + return err; + + } + +// ----------------------------------------------------------------------------- +// DIscDevice::QueueFrame +// Queue frames that will be sent to Domestic OS +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt DIscDevice::QueueFrame( + const TUint16 aChannelId, + const TDesC8* aFrame, + const TAny* aChannelPtr, + TAny* aFrameInfo ) + { + C_TRACE( ( _T( "DIscDevice::QueueFrame(0x%x, 0x%x, 0x%x, 0x%x)" ), aChannelId, aFrame, aChannelPtr, aFrameInfo ) ); + + TInt error = KErrNone; + + // control channel frame ( highest priority ) + if ( aChannelId == KIscControlChannel ) + { + C_TRACE( ( _T( "DIscDevice::QueueFrame control frame queue" ) ) ); + //add to control frame queue + error = iControlSendQueue->Add( ( TDes8* )aFrame, aChannelId, ( DIscChannel* )aChannelPtr, aFrameInfo ); + } + else + { + C_TRACE( ( _T( "DIscDevice::QueueFrame send queue" ) ) ); + // add to send queue + error = iSendQueue->Add( ( TDes8* )aFrame, aChannelId, ( DIscChannel* )aChannelPtr, aFrameInfo ); + } + + C_TRACE( ( _T( "DIscDevice::QueueFrame - return 0x%x" ), error ) ); + return error; + } + + +// ----------------------------------------------------------------------------- +// DIscDevice::CancelSending +// Cancels sending of frames to Domestic OS +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt DIscDevice::CancelSending( const TUint16 aChannelId, const TAny* aChannelPtr ) + { + C_TRACE( ( _T( "DIscDevice::CancelSending - Caller is channel: %d (0x%x)" ), aChannelId, aChannelPtr ) ); + + TInt error( KErrNotFound ); + TInt irqLevel( 0 ); + + TInt counterA( 0 ); + TInt counterB( 0 ); + + TIscSendFrameInfo* temp = NULL; + TDes8* frame = NULL; + + irqLevel = DisableIrqs(); + + if ( KIscControlChannel == aChannelId ) + { + // empty control send queue + while ( !iControlSendQueue->Empty() ) + { + temp = iControlSendQueue->GetFirstFrameInfo(); + frame = ( TDes8* )iControlSendQueue->RemoveFirst(); + if ( temp && frame ) + { + if ( temp->iChannelId == aChannelId && + temp->iChannelPtr == ( DIscChannel* )aChannelPtr ) + { + // sender found, no need to store the frame + counterB++; + } + else + { + iTempQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo ); + } + } + else + { + // should never came here + TRACE_ASSERT_ALWAYS; + } + counterA++; + temp = NULL; + frame = NULL; + } + + while ( !iTempQueue->Empty() ) + { + temp = iTempQueue->GetFirstFrameInfo(); + frame = ( TDes8* )iTempQueue->RemoveFirst(); + if ( temp && frame ) + { + iControlSendQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo ); + } + else + { + // should never came here + TRACE_ASSERT_ALWAYS; + } + temp = NULL; + frame = NULL; + } + } + else + { + // empty normal send queue + while ( !iSendQueue->Empty() ) + { + temp = iSendQueue->GetFirstFrameInfo(); + frame = ( TDes8* )iSendQueue->RemoveFirst(); + if ( temp && frame ) + { + if ( temp->iChannelId == aChannelId && + temp->iChannelPtr == ( DIscChannel* )aChannelPtr ) + { + // sender found, no need to store frame + counterB++; + } + else + { + iTempQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo ); + } + } + else + { + // should never came here + TRACE_ASSERT_ALWAYS; + } + counterA++; + temp = NULL; + frame = NULL; + } + + while ( !iTempQueue->Empty() ) + { + temp = iTempQueue->GetFirstFrameInfo(); + frame = ( TDes8* )iTempQueue->RemoveFirst(); + if ( temp && frame ) + { + iSendQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo ); + } + else + { + // should never came here + TRACE_ASSERT_ALWAYS; + } + + temp = NULL; + frame = NULL; + } + } + + RestoreIrqs( irqLevel ); + + C_TRACE( ( _T( "DIscDevice::CancelSending() - Frames in queue: Before: %d, After: %d" ), counterA, ( counterA-counterB ) ) ); + C_TRACE( ( _T( "DIscDevice::CancelSending() - So channel 0x%x 0x%x had %d pending messages!" ), aChannelId, aChannelPtr, counterB ) ); + + // if there weren't any frames that were cancelled return KErrNotFound, otherwise return KErrNone + if ( counterB > 0 ) + { + error = KErrNone; + } + + return error; + + } + +// ----------------------------------------------------------------------------- +// DIscDevice::FlushQueues +// Adds Dfc to empty queues +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C void DIscDevice::FlushQueues() + { + C_TRACE( ( _T( "DIscDevice::FlushQueues()" ) ) ); + + if ( NKern::CurrentContext() == NKern::EInterrupt ) + { + iSendDfc->Add(); + } + else + { + iSendDfc->Enque(); + } + + } + +// ----------------------------------------------------------------------------- +// DIscDevice::CompleteRequest +// Function to complete user side asynchronous request +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +// This method has been modified to allow channel sharing between application. +// The completion routine uses directly a pointer on a DLogicalChannel instead of a channel index +// +EXPORT_C void DIscDevice::CompleteRequest( + TUint16 aOperation, + TInt aCompleteStatus, + const TAny* aChannelPtr ) + { + C_TRACE( ( _T( "DIscDevice::CompleteRequest(0x%x, 0x%x, 0x%x)" ), aOperation, aCompleteStatus, aChannelPtr ) ); + + DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; + TInt error = IscChannelContainer::ValidateChannel( tempPtr ); + if( error == KErrNone ) + { + tempPtr->CompleteRequest( aOperation, aCompleteStatus ); + } + + C_TRACE( ( _T( "DIscDevice::CompleteRequest - return void" ) ) ); + } + +// ----------------------------------------------------------------------------- +// DIscDevice::CopyFromUserBuffer +// +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt DIscDevice::CopyFromUserBuffer( + const TDesC8& aUserBuffer, + TDes8& aKernelBuffer, + const TAny* aChannelPtr, + const TInt aOffset ) + { + C_TRACE( ( _T( "DIscDevice::CopyFromUserBuffer(0x%x, 0x%x, 0x%x, 0x%x)" ), &aUserBuffer, &aKernelBuffer, aChannelPtr, aOffset ) ); + + // Check if channel pointer is valid. + DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; + TInt error = IscChannelContainer::ValidateChannel( tempPtr ); + if( error == KErrNone ) + { + error = tempPtr->CopyFromUserBuffer( aUserBuffer, aKernelBuffer, aOffset ); + } + C_TRACE( ( _T( "DIscDevice::CopyFromUserBuffer - return %d" ), error ) ); + return error; + + } + +// ----------------------------------------------------------------------------- +// DIscDevice::CopyToUserBuffer +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt DIscDevice::CopyToUserBuffer( + TAny* aUserBuffer, + const TDesC8& aKernelBuffer, + const TAny* aChannelPtr, + const TInt aOffset ) + { + C_TRACE( ( _T( "DIscDevice::CopyToUserBuffer(0x%x, 0x%x, 0x%x)" ), aUserBuffer, &aKernelBuffer, aChannelPtr ) ); + + DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; + TInt error = IscChannelContainer::ValidateChannel( tempPtr ); + if( KErrNone == error ) + { + error = tempPtr->ThreadWrite( aUserBuffer, &aKernelBuffer, aOffset ); + } + C_TRACE( ( _T( "DIscDevice::CopyToUserBuffer - return %d" ), error ) ); + return error; + + } + +// ----------------------------------------------------------------------------- +// DIscMultiplexerBase::GetThreadPtr +// Returns user side thread. Ownership is not given. +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +EXPORT_C DThread* DIscDevice::GetThreadPtr( const TAny* aChannelPtr ) + { + C_TRACE( ( _T( "DIscMultiplexerBase::GetThreadPtr(0x%x)" ), aChannelPtr ) ); + DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; + TInt error = IscChannelContainer::ValidateChannel( tempPtr ); + DThread* tmp = NULL; + if( KErrNone == error ) + { + tmp = tempPtr->GetDThread(); + } + else + { + C_TRACE( ( _T( "DIscMultiplexerBase::GetThreadPtr failed return NULL" ) ) ); + } + C_TRACE( ( _T( "DIscMultiplexerBase::GetThreadPtr return 0x%x" ), tmp ) ); + return tmp; + + } + +// ----------------------------------------------------------------------------- +// DIscDevice::Flush +// Dfc to empty control channel and other send queues +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +void DIscDevice::Flush( TAny* aPtr ) + { + C_TRACE( ( _T( "DIscDevice::Flush(0x%x)" ), aPtr ) ); + DIscDevice* device = ( DIscDevice* )aPtr; + + TDes8* frame = NULL; + TIscSendFrameInfo* temp = NULL; + + TInt irqLevel(0); + + // If transmission is asynchronous and there can't be + // several requests at the same time + if ( !iIscDataTransmissionInterface->IsWritePending() ) + { + irqLevel = DisableIrqs(); + if ( !iControlSendQueue->Empty() ) + { + temp = iControlSendQueue->GetFirstFrameInfo(); + frame = ( TDes8* )iControlSendQueue->RemoveFirst(); + } + else + { + temp = iSendQueue->GetFirstFrameInfo(); + frame = ( TDes8* )iSendQueue->RemoveFirst(); + } + RestoreIrqs( irqLevel ); + C_TRACE( ( _T( "DIscDevice::Flush after RESTOREIRQS" ) ) ); + if ( frame ) + iIscDataTransmissionInterface->SendFrame( *frame, device->iSendDfc, temp->iFrameInfo ); + } + C_TRACE( ( _T( "DIscDevice::Flush - return 0x0" ) ) ); + + } + + +// ----------------------------------------------------------------------------- +// DIscDevice::ConnectionStatus +// Function to tell current status of connection to Domestic OS +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +TInt DIscDevice::ConnectionStatus() + { + return iConnectionStatus; + } + +// ----------------------------------------------------------------------------- +// DIscDevice::DisableIrqs +// Function to disable interrupts +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +TInt DIscDevice::DisableIrqs() + { +#ifndef __WINS__ + return NKern::DisableInterrupts( KIscInterruptLevelTwo ); +#else //__WINS__ + EnterCriticalSection( &g_IscDTBCriticalSection ); + return KErrNone; +#endif//__WINS__ + } + +// ----------------------------------------------------------------------------- +// DIscDevice::RestoreIrqs +// Function to restore interrupts +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +#ifndef __WINS__ +void DIscDevice::RestoreIrqs( + TInt aLevel ) + { + NKern::RestoreInterrupts( aLevel ); + +#else //__WINS__ +void DIscDevice::RestoreIrqs( + TInt ) + { + LeaveCriticalSection( &g_IscDTBCriticalSection ); +#endif//__WINS__ + } + + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// ----------------------------------------------------------------------------- +// E32Dll +// Epoc Kernel Architecture 2 style entry point +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +DECLARE_STANDARD_LDD() + { + DLogicalDevice* device = new DIscDevice; + if ( !device ) + { + ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscPanicCreateLogicalDevice ); + } + return device; + } + +// End of File