diff -r 000000000000 -r 63b37f68c1ce connectivitylayer/isce/isaaccessldd_ldd/src/isauserchannel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectivitylayer/isce/isaaccessldd_ldd/src/isauserchannel.cpp Fri Nov 06 17:28:23 2009 +0000 @@ -0,0 +1,1658 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include "queue.h" // For DQueue +#include "isauserchannel.h" // For DISAUserChannel +#include "iadtrace.h" // For C_TRACE, ASSERT_RESET.. and fault codes. +#include "isaaccessextension.h" // For DIsaAccessExtension +#include "iadnokiadefinitions.h" // For checking allowed user channels. + +// Extracting and adding the pipeheader. +#include // For ISI_HEADER_SIZE +#include // For PNS_PIPE_DATA_OFFSET_DATA +#include "OstTraceDefinitions.h" +#ifdef OST_TRACE_COMPILER_IN_USE +#include "isauserchannelTraces.h" +#endif +const TInt KPipeDataHeader( ISI_HEADER_SIZE + PNS_PIPE_DATA_OFFSET_DATA ); + +const TInt KFirstParam( 0 ); +const TInt KSecondParam( 1 ); +const TInt KThirdParam( 2 ); +const TInt KNoParams( KErrNone ); +const TInt KOneParam( 1 ); +const TInt KTwoParams( 2 ); +const TInt KThreeParams( 3 ); + +const TInt KDestStartOffset( 0 ); +// +// user <-> kernel interaction() done in LDD DFC thread +// +// kernel<->kernel interaction() done in Extension DFC thread +// +////////////////// NOTE! ///////////////////////////////////////// +// +// SYNCHRONIZATION: +// Check sync of mutex guarded shread members. +// Rule1: No blocking operation like trace prints inside mutex guareded code sections. +// +// DEMAND_PAGING +// Receive (write k->u) is done only in LDD thread context to allow Extension thread to continue when dp swaps. +// Send ((write u->k) is not done at the moment in LDD thread context only. Check is it possible to happend (not to be in usable memory after send (unlikely?)). + +// Change this to use UniqueID of DThread instead and to extension +void DISAUserChannel::CheckDfc() + { + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_CHECKDFC_ENTRY, ">DISAUserChannel::CheckDfc" ); + + DObject* tempObj = reinterpret_cast( &Kern::CurrentThread() ); + TUint8* buffer = ( TUint8* )Kern::Alloc( 100 ); + TPtr8* bufferPtr = new ( TPtr8 )( buffer, 100 ); + tempObj->Name( *bufferPtr ); + C_TRACE( ( _T( "DISAUserChannel::CheckDfc" ) ) ); + if ( bufferPtr->Compare( KIADLddDfc ) != KErrNone ) + { + for( TInt i( 0 );i < bufferPtr->Length(); ++i ) + { + C_TRACE( ( _T( "%c" ), i, bufferPtr->Ptr()[ i ] ) ); + } + ASSERT_RESET_ALWAYS( 0, EIADWrongDFCQueueUsed| EIADFaultIdentifier3 << KFaultIdentifierShift ); + } + Kern::Free( buffer ); + delete bufferPtr; + bufferPtr = NULL; + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_CHECKDFC_EXIT, "DISAUserChannel::DISAUserChannel" ); + + C_TRACE( ( _T( "DISAUserChannel::DISAUserChannel ->" ) ) ); + + iExtensionApi = DIsaAccessExtension::GetChannel2IADApi(); + iEmptyRxQueueDfc = new TDfc( EmptyRxQueueDfc, this, DIsaAccessExtension::GetDFCThread( EIADLddDfcQueue ), KIADLddEmptyRxQueuePriori ); + iEmptyDataRxQueueDfc = new TDfc( EmptyDataRxQueueDfc, this, DIsaAccessExtension::GetDFCThread( EIADLddDfcQueue ), KIADLddEmptyDataRxQueuePriori ); + ASSERT_RESET_ALWAYS( iExtensionApi && iEmptyRxQueueDfc && iEmptyDataRxQueueDfc, + EIADMemoryAllocationFailure | EIADFaultIdentifier20 << KFaultIdentifierShift ); + iConnectionStatusDfc = new TDfc( ConnectionStatusDfc, this, DIsaAccessExtension::GetDFCThread( EIADLddDfcQueue ), KIADLddConnStatPriori ); + iFlowCtrlStatusDfc = new TDfc( FlowCtrlStatusDfc, this, DIsaAccessExtension::GetDFCThread( EIADLddDfcQueue ), KIADLddFlowStatPriori ); + iCompleteChannelRequestDfc = new TDfc( CompleteChReqDfc, this, DIsaAccessExtension::GetDFCThread( EIADLddDfcQueue ), KIADLddCompleteChannelPriori ); + // For sync between ldd <-> extension dfc threads. NOTE! must not be held when accessing to user memory! + iChFastMutex = new NFastMutex(); + ASSERT_RESET_ALWAYS( iConnectionStatusDfc && iFlowCtrlStatusDfc && iCompleteChannelRequestDfc && iChFastMutex, + EIADMemoryAllocationFailure | EIADFaultIdentifier21 << KFaultIdentifierShift ); + + iCleanDfc = new TDfc( CleanBlocksDfc, this, DIsaAccessExtension::GetDFCThread( EIADExtensionDfcQueue ), KIADLddEmptyRxQueuePriori ); + iCleanDataDfc = new TDfc( CleanDataBlocksDfc, this, DIsaAccessExtension::GetDFCThread( EIADExtensionDfcQueue ), KIADLddEmptyDataRxQueuePriori ); + ASSERT_RESET_ALWAYS( iCleanDfc && iCleanDataDfc, EIADMemoryAllocationFailure | EIADFaultIdentifier21 << KFaultIdentifierShift ); + + C_TRACE( ( _T( "DISAUserChannel::DISAUserChannel <-" ) ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_DISAUSERCHANNEL_EXIT, "DISAUserChannel::MsgQueFunc;aPtr=%x", ( TUint )( aPtr ) ); + + DISAUserChannel* ch = reinterpret_cast( aPtr ); + ch->HandleMsg( ch->iMsgQue.iMessage ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_MSGQUEFUNC_EXIT, "DISAUserChannel::~DISAUserChannel" ); + + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel 0x%x 0x%x ->" ), iChannelNumber, this ) ); + OstTraceExt5( TRACE_NORMAL, DISAUSERCHANNEL_DISAUSERCHANNEL, "DISAUserChannel::~DISAUserChannel;iEmptyRxQueueDfc=%x;iEmptyDataRxQueueDfc=%x;iConnectionStatusDfc=%x;iFlowCtrlStatusDfc=%x;iCompleteChannelRequestDfc=%x", (TUint)iEmptyRxQueueDfc, (TUint)iEmptyDataRxQueueDfc, (TUint)iConnectionStatusDfc, (TUint)iFlowCtrlStatusDfc, (TUint)iCompleteChannelRequestDfc ); + if( iEmptyRxQueueDfc ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iEmptyRxQueueDfc 0x%x" ), iEmptyRxQueueDfc ) ); + iEmptyRxQueueDfc->Cancel(); + delete iEmptyRxQueueDfc; + iEmptyRxQueueDfc = NULL; + } + if( iEmptyDataRxQueueDfc ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iEmptyDataRxQueueDfc 0x%x" ), iEmptyDataRxQueueDfc ) ); + iEmptyDataRxQueueDfc->Cancel(); + delete iEmptyDataRxQueueDfc; + iEmptyDataRxQueueDfc = NULL; + } + if( iConnectionStatusDfc ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iConnectionStatusDfc 0x%x" ), iConnectionStatusDfc ) ); + iConnectionStatusDfc->Cancel(); + delete iConnectionStatusDfc; + iConnectionStatusDfc = NULL; + } + if( iFlowCtrlStatusDfc ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iFlowCtrlStatusDfc 0x%x" ), iFlowCtrlStatusDfc ) ); + iFlowCtrlStatusDfc->Cancel(); + delete iFlowCtrlStatusDfc; + iFlowCtrlStatusDfc = NULL; + } + if( iCompleteChannelRequestDfc ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iCompleteChannelRequestDfc 0x%x" ), iCompleteChannelRequestDfc ) ); + iCompleteChannelRequestDfc->Cancel(); + delete iCompleteChannelRequestDfc; + iCompleteChannelRequestDfc = NULL; + } + OstTraceExt4( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_DISAUSERCHANNEL, "DISAUserChannel::~DISAUserChannel;iRx=%x;iDataRx=%x;iRxDeAllocate=%x;iDataRxDeAllocate=%x", (TUint)iRx, (TUint)iDataRx, (TUint)iRxDeAllocate, (TUint)iDataRxDeAllocate ); + + if( iRx ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iRx 0x%x" ), iRx ) ); + delete iRx; + iRx = NULL; + } + if( iDataRx ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iDataRx 0x%x" ), iDataRx ) ); + delete iDataRx; + iDataRx = NULL; + } + if( iRxDeAllocate ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iRxDeAllocate 0x%x" ), iRxDeAllocate ) ); + delete iRxDeAllocate; + iRxDeAllocate = NULL; + } + if( iDataRxDeAllocate ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iDataRxDeAllocate 0x%x" ), iDataRxDeAllocate ) ); + delete iDataRxDeAllocate; + iDataRxDeAllocate = NULL; + } + // Not owned + OstTraceExt4( TRACE_NORMAL, DUP9_DISAUSERCHANNEL_DISAUSERCHANNEL, "DISAUserChannel::~DISAUserChannel;iIADConnectionStatusPtr=%x;iIADFlowControlStatusPtr=%x;iReceiveBufPtr=%x;iDataReceiveBufPtr=%x", (TUint)iIADConnectionStatusPtr, (TUint)iIADFlowControlStatusPtr, (TUint)iReceiveBufPtr, (TUint)iDataReceiveBufPtr ); + + if( iIADConnectionStatusPtr ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iIADConnectionStatusPtr 0x%x" ), iIADConnectionStatusPtr ) ); + iIADConnectionStatusPtr = NULL; + } + if( iIADFlowControlStatusPtr ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iIADFlowControlStatusPtr 0x%x" ), iIADFlowControlStatusPtr ) ); + iIADFlowControlStatusPtr = NULL; + } + if( iReceiveBufPtr ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iReceiveBufPtr 0x%x" ), iReceiveBufPtr ) ); + iReceiveBufPtr = NULL; + } + if( iDataReceiveBufPtr ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iDataReceiveBufPtr 0x%x" ), iDataReceiveBufPtr ) ); + iDataReceiveBufPtr = NULL; + } + + OstTraceExt4( TRACE_NORMAL, DUP10_DISAUSERCHANNEL_DISAUSERCHANNEL, "DISAUserChannel::~DISAUserChannel;iNeededBufLen=%x;iNeededDataBufLen=%x;iIADUserChannelNumberPtr=%x;iReqQueue=%x", (TUint)iNeededBufLen, (TUint)iNeededDataBufLen, (TUint)iIADUserChannelNumberPtr, (TUint)iReqQueue ); + + + if( iNeededBufLen ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iNeededBufLen 0x%x" ), iNeededBufLen ) ); + iNeededBufLen = NULL; + } + if( iNeededDataBufLen ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iNeededDataBufLen 0x%x" ), iNeededDataBufLen ) ); + iNeededDataBufLen = NULL; + } + if( iIADUserChannelNumberPtr ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iIADUserChannelNumberPtr 0x%x" ), iIADUserChannelNumberPtr ) ); + iIADUserChannelNumberPtr = NULL; + } + + if( iReqQueue ) + { + delete iReqQueue; + iReqQueue = NULL; + } + iPep = NULL; + iExtensionApi = NULL; + // owned + if( iChFastMutex ) + { + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel iChFastMutex" ) ) ); + delete iChFastMutex; + iChFastMutex = NULL; + } + Kern::SafeClose( reinterpret_cast(iThread), NULL ); + C_TRACE( ( _T( "DISAUserChannel::~DISAUserChannel 0x%x 0x%x <-" ), iChannelNumber, this ) ); + + } + +TInt DISAUserChannel::DoCreate( + TInt, //aUnit, // Used to hold channelid now in anInfo instead no need to extension device + const TDesC8* anInfo, // Channelid now in anInfo instead no need to extension device + const TVersion& // aVer // Not used at the moment. + ) + { + OstTraceExt2( TRACE_NORMAL, DISAUSERCHANNEL_DOCREATE_ENTRY, "DISAUserChannel::DoCreate;anInfo=%x;this=%x", ( TUint )( anInfo ), (TUint)(this) ); + + C_TRACE( ( _T( "DISAUserChannel::DoCreate 0x%x 0x%x ->" ), iChannelNumber, anInfo ) ); + if( !Kern::CurrentThreadHasCapability( ECapabilityCommDD, __PLATSEC_DIAGNOSTIC_STRING( "Check by: ISAAccessDriver" ) ) ) return KErrPermissionDenied; + ASSERT_RESET_ALWAYS( anInfo, EIADChannelNumberNotSpecifiedInInfo | EIADFaultIdentifier1 << KFaultIdentifierShift ); + // Check for channel number inside anInfo. + ASSERT_RESET_ALWAYS( anInfo->Length() > 0 , EIADOverTheLimits | EIADFaultIdentifier39 << KFaultIdentifierShift ); + TUint16 channel = static_cast( ( *anInfo )[ 0 ] ); + ASSERT_RESET_ALWAYS( ( channel < EIADNokiaLastUserChannel ),EIADWrongParameter | EIADFaultIdentifier19 << KFaultIdentifierShift ); + iChannelNumber = ~channel; // In user thread context thread in CS, cannot be pre-empted. + C_TRACE( ( _T( "DISAUserChannel::DoCreate channelnumber 0x%x 0x%x" ), iChannelNumber, this ) ); + iRx = new DQueue( KIADLddRxQueuSize ); + iDataRx =new DQueue( KIADLddDataRxQueuSize ); + iReqQueue = new DReqQueue(); + ASSERT_RESET_ALWAYS( iRx && iDataRx && iReqQueue, EIADMemoryAllocationFailure | EIADFaultIdentifier22 << KFaultIdentifierShift ); + iRxDeAllocate = new DQueue( KIADLddRxQueuSize ); + iDataRxDeAllocate = new DQueue( KIADLddDataRxQueuSize ); + // Changed to extension DFC to guarantee that extension is handled only by one thread extensionDFC. + // Other DFC functions handling user<->kernel copying done in ldd DFC. + SetDfcQ( DIsaAccessExtension::GetDFCThread( EIADExtensionDfcQueue ) );// this DFCFunction prio is now 1 by the LDD framework if needed increase? + iMsgQ.Receive(); + iMsgQue.SetDfcQ( DIsaAccessExtension::GetDFCThread( EIADLddDfcQueue ) ); + iMsgQue.Receive(); + DObject* thread = reinterpret_cast( iThread ); + // Open is needed to increase ref count to calling thread that is decreased in Kern::SafeClose + // Possible returns KErrNone ? KErrGeneral + TInt threadOpen( thread->Open() ); + TRACE_ASSERT_INFO( threadOpen == KErrNone, (TUint8)iChannelNumber << KChannelNumberShift ); + C_TRACE( ( _T( "DISAUserChannel::DoCreate 0x%x %d <-" ), iChannelNumber, threadOpen ) ); + + OstTraceExt3( TRACE_NORMAL, DISAUSERCHANNEL_DOCREATE_EXIT, "DISAUserChannel::HandleMsg;aMsg=%x", ( TUint )( aMsg ) ); + + C_TRACE( ( _T( "DISAUserChannel::HandleMsg 0x%x->" ), aMsg ) ); + TThreadMessage& m= *( static_cast< TThreadMessage* >( aMsg ) ); + TInt id( m.iValue ); + if( static_cast( ECloseMsg ) == id ) + { + C_TRACE( ( _T( "DISAUserChannel::HandleMsg ECloseMsg 0x%x" ), iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DISAUSERCHANNEL_HANDLEMSG, "DISAUserChannel::HandleMsg ECloseMsg;iChannelNumber=%hx", iChannelNumber ); + + m.Complete( HandleSyncRequest( EIADClose, NULL ), EFalse ); + } + else if( KMaxTInt == id ) + { + C_TRACE( ( _T( "DISAUserChannel::HandleMsg cancel" ) ) ); + OstTrace0( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_HANDLEMSG, "DISAUserChannel::HandleMsg cancel" ); + + DoCancel( id, m.Int0() ); + m.Complete( KErrNone, ETrue ); + } + else + { + ASSERT_RESET_ALWAYS( ( KErrNotFound < id ), EIADWrongRequest | EIADFaultIdentifier5 << KFaultIdentifierShift ); + C_TRACE( ( _T( "DISAUserChannel::HandleMsg completeValue == KErrNone" ) ) ); + OstTrace1( TRACE_NORMAL, DUP2_DISAUSERCHANNEL_HANDLEMSG, "DISAUserChannel::HandleMsg;id=%d", id ); + + TInt completeValue( KErrNone ); + TInt ulen( KErrNotFound ); + switch ( id ) + { + case EIADClose: + case EIADGetConnectionStatus: + case EIADGetMaxDataSize: + case EIADResetQueues: + case EIADGetFlowControlStatus: +#if (NCP_COMMON_SOS_VERSION_SUPPORT >= SOS_VERSION_95) + case EIADReturnLoan: +#endif + { + ulen = KNoParams; + break; + } + case EIADAsyncClose: + case EIADSend: + case EIADDataSend: + case EIADSubscribeIndications: + case EIADSendIndication: + case EIADSubscribeIndications32Bit: +#if (NCP_COMMON_SOS_VERSION_SUPPORT >= SOS_VERSION_95) + case EIADLoan: +#endif + { + ulen = KOneParam; + break; + } + case EIADAsyncNotifyFlowControlStatus: + case EIADAsyncNotifyConnectionStatus: + case EIADAsyncSend: + case EIADAsyncDataSend: + case EIADAsyncSubscribeIndications: + case EIADAsyncSendIndication: + case EIADAsyncSubscribeIndications32Bit: + //case EIADAsyncFTDInformation: + { + ulen = KTwoParams; + break; + } + case EIADAsyncOpen: + case EIADAsyncReceive: + case EIADAsyncDataReceive: + { + ulen = KThreeParams; + break; + } + default: + { + ASSERT_RESET_ALWAYS( 0, EIADWrongRequest | EIADFaultIdentifier6 << KFaultIdentifierShift ); + break; + } + } + TUint32* table[ KThreeParams ]; + completeValue = Kern::ThreadRawRead( iThread, m.Ptr0(), table, ulen * sizeof( TAny* ) ); + if( completeValue == KErrNone ) + { + switch( id ) + { + // All asynchronous requests. + case EIADAsyncOpen: + case EIADAsyncNotifyConnectionStatus: + case EIADAsyncClose: + case EIADAsyncReceive: + case EIADAsyncDataReceive: + case EIADAsyncNotifyFlowControlStatus: + case EIADAsyncSend: + case EIADAsyncDataSend: + case EIADAsyncSubscribeIndications: + case EIADAsyncSendIndication: + case EIADAsyncSubscribeIndications32Bit: + //case EIADAsyncFTDInformation: + { + // No need to check return value in async functions, completed to user + HandleAsyncRequest( id, table ); + break; + } + case EIADClose: + case EIADSend: + case EIADDataSend: + case EIADSubscribeIndications: + case EIADSendIndication: + case EIADGetMaxDataSize: + case EIADSubscribeIndications32Bit: + case EIADGetConnectionStatus: + case EIADResetQueues: + case EIADGetFlowControlStatus: +#if (NCP_COMMON_SOS_VERSION_SUPPORT >= SOS_VERSION_95) + case EIADLoan: + case EIADReturnLoan: +#endif + { + completeValue = HandleSyncRequest( id, table ); + break; + } + default: + { + ASSERT_RESET_ALWAYS( 0, EIADWrongRequest | EIADFaultIdentifier7 << KFaultIdentifierShift ); + break; + } + } + } + m.Complete( completeValue, ETrue ); + } + C_TRACE( ( _T( "DISAUserChannel::HandleMsg <-" ) ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_HANDLEMSG_EXIT, "" ), aReqNo, a1, iChannelNumber ) ); + ASSERT_RESET_ALWAYS( aReqNo >= ( TInt ) EMinRequestId, EIADWrongRequest | EIADFaultIdentifier8 << KFaultIdentifierShift ); +#if (NCP_COMMON_SOS_VERSION_SUPPORT >= SOS_VERSION_95) + ASSERT_RESET_ALWAYS( aReqNo <= EIADReturnLoan || aReqNo == KMaxTInt, + EIADWrongRequest | EIADFaultIdentifier1 << KFaultIdentifierShift ); + ASSERT_RESET_ALWAYS( ( iChannelNumber < EIADNokiaLastUserChannel || EIADAsyncOpen == aReqNo || EIADLoan == aReqNo ), + EIADWrongParameter | EIADFaultIdentifier18 << KFaultIdentifierShift ); +#else + ASSERT_RESET_ALWAYS( aReqNo <= EIADDeAllocateBlock || aReqNo == KMaxTInt, + EIADWrongRequest | EIADFaultIdentifier1 << KFaultIdentifierShift ); + ASSERT_RESET_ALWAYS( ( iChannelNumber < EIADNokiaLastUserChannel || EIADAsyncOpen == aReqNo ), + EIADWrongParameter | EIADFaultIdentifier18 << KFaultIdentifierShift ); +#endif + TInt result( KErrNotFound ); + // All request go now in kernel context: easies synchronization between isa access threads. + // We have the option still to use user context here. (CAREFULL IF DOING SO WITH DATA CORRUPTION) + // Give to kernel address space in EXT DFC context. + // Demand paging: if needed change this DFC to LDD DFC and + // give the read data from LDD DFC to EXT DFC via another SendReceive (MessageQue). + TThreadMessage& m=Kern::Message(); + m.iValue = aReqNo; + m.iArg[ KFirstParam ] = a1; + m.iArg[ KSecondParam ] = NULL; + // Own kernelmessage queu for receive and datareceive which are not handling shareddata below channel (in extension). + if( aReqNo == EIADAsyncReceive || aReqNo == EIADAsyncDataReceive ) + { + result = m.SendReceive( &iMsgQue ); + } + else + { + result = m.SendReceive( &iMsgQ ); + } + C_TRACE( ( _T( "DISAUserChannel::Request %d, 0x%x, 0x%x %d <-" ), aReqNo, a1, iChannelNumber, result ) ); + OstTrace1( TRACE_NORMAL, DISAUSERCHANNEL_REQUEST, "DISAUserChannel::CompleteChannelRequest;aRequest=%d;aStatusToComplete=%d;iChannelNumber=%hx", aRequest, aStatusToComplete, iChannelNumber ); + + C_TRACE( ( _T( "DISAUserChannel::CompleteChannelRequest %d %d 0x%x ->" ), aRequest, aStatusToComplete, iChannelNumber ) ); + ASSERT_CONTEXT_ALWAYS( NKern::EThread, 0 ); + TIADReq req( static_cast( aRequest ), aStatusToComplete ); + if( iReqQueue->Add( req ) ) + { + TRACE_ASSERT_INFO( !iCompleteChannelRequestDfc->Queued(), (TUint8)iChannelNumber << KChannelNumberShift | (TUint16)aRequest ); + iCompleteChannelRequestDfc->Enque(); + } + C_TRACE( ( _T( "DISAUserChannel::CompleteChannelRequest %d %d 0x%x <-" ), aRequest, aStatusToComplete, iChannelNumber ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_COMPLETECHANNELREQUEST_EXIT, "DISAUserChannel::CompleteChReqDfc;aPtr=%x", ( TUint )( aPtr ) ); + + C_TRACE( ( _T( "DISAUserChannel::CompleteChReqDfc ->" ) ) ); + // Make sure that user side is accessed only by ldd DFCThread. + ASSERT_CONTEXT_ALWAYS( NKern::EThread, 0 ); + ASSERT_DFCTHREAD_INLDD(); + DISAUserChannel* chPtr = reinterpret_cast( aPtr ); + C_TRACE( ( _T( "DISAUserChannel::CompleteChReqDfc 0x%x" ), chPtr->iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DISAUSERCHANNEL_COMPLETECHREQDFC, "DISAUserChannel::CompleteChReqDfc;iChannelNumber=%hx", chPtr->iChannelNumber ); + + TIADReq requ = chPtr->iReqQueue->Get(); + if( EIADAsyncOpen == requ.iRequest ) + { + C_TRACE( ( _T( "DISAUserChannel::CompleteChReqDfc req complete open" ) ) ); + OstTraceExt1( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_COMPLETECHREQDFC, "DISAUserChannel::CompleteChReqDfc;iChannelNumber=%hx", chPtr->iChannelNumber ); + + TAny* tempUserChNmbrPtr( chPtr->iIADUserChannelNumberPtr ); + // Check of KErrNone and KErrInUse (same object same id open) and in only those cases ~iCh = ~~iCh kernel already has. + TUint16 chNumber( ( KErrNone == requ.iCompleteStatus || KErrInUse == requ.iCompleteStatus ? ~chPtr->iChannelNumber : KNotInitializedChannel ) ); + chPtr->iChannelNumber = chNumber; + ASSERT_RESET_ALWAYS( tempUserChNmbrPtr, 0 ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadRawWrite( chPtr->iThread, tempUserChNmbrPtr, &chNumber, sizeof(TUint16), chPtr->iThread ), + EIADDesWriteFailed | ( TUint8 )( chPtr->iChannelNumber ) << KChannelNumberShift ); + } + // Request was already pending.. + TRequestStatus* status( chPtr->iReqQueue->GetReq( requ.iRequest ) ); + Kern::RequestComplete( chPtr->iThread, status, requ.iCompleteStatus ); + C_TRACE( ( _T( "DISAUserChannel::CompleteChReqDfc req complete %d stat %d" ), requ.iRequest, requ.iCompleteStatus ) ); + OstTraceExt2( TRACE_NORMAL, DUP2_DISAUSERCHANNEL_COMPLETECHREQDFC, "DISAUserChannel::CompleteChReqDfc complete %x stat %x", requ.iRequest, requ.iCompleteStatus ); + + chPtr->iReqQueue->SetReq( requ.iRequest, NULL ); + if( !chPtr->iReqQueue->Empty() ) + { + CompleteChReqDfc( chPtr ); + } + C_TRACE( ( _T( "DISAUserChannel::CompleteChReqDfc <-" ), chPtr->iChannelNumber ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_COMPLETECHREQDFC_EXIT, "DISAUserChannel::NotifyConnectionStatus;aStatus=%x", ( TUint )&( aStatus ) ); + + C_TRACE( ( _T( "DISAUserChannel::NotifyConnectionStatus 0x%x %d ->" ), iChannelNumber, iConnectionStatus ) ); + // Atomic STR no need to synch. + iConnectionStatus = aStatus; + ASSERT_RESET_ALWAYS( !iConnectionStatusDfc->Queued(), EIADDFCAlreadyQueued | EIADFaultIdentifier2 << KFaultIdentifierShift ); + iConnectionStatusDfc->Enque(); + C_TRACE( ( _T( "DISAUserChannel::NotifyConnectionStatus 0x%x %d <-" ), iChannelNumber, iConnectionStatus ) ); + + OstTraceExt2( TRACE_NORMAL, DISAUSERCHANNEL_NOTIFYCONNECTIONSTATUS_EXIT, "" ) ) ); + ASSERT_DFCTHREAD_INLDD(); + DISAUserChannel* chPtr = reinterpret_cast( aPtr ); + if( chPtr->iIADConnectionStatusPtr ) + { + + TIADReq req( EIADAsyncNotifyConnectionStatus, KErrNone ); + if( chPtr->iReqQueue->Add( req ) ) + { + TInt temp( chPtr->iConnectionStatus ); + C_TRACE( ( _T( "DISAUserChannel::NotifyConnectionStatusDfc 0x%x request active, writing %d" ), chPtr->iChannelNumber, temp ) ); + OstTraceExt2( TRACE_NORMAL, DISAUSERCHANNEL_CONNECTIONSTATUSDFC, "DISAUserChannel::ConnectionStatusDfc;chPtr->iChannelNumber=%hx;temp=%d", chPtr->iChannelNumber, temp ); + + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadRawWrite( chPtr->iThread, chPtr->iIADConnectionStatusPtr, &temp, sizeof(TUint16), chPtr->iThread ), + EIADDesWriteFailed | ( TUint8 )( chPtr->iChannelNumber ) << KChannelNumberShift | EIADFaultIdentifier1 << KFaultIdentifierShift ); + TRACE_ASSERT_INFO( !chPtr->iCompleteChannelRequestDfc->Queued(), ( TUint8 )( chPtr->iChannelNumber ) << KChannelNumberShift ); + CompleteChReqDfc( chPtr ); + } + } + C_TRACE( ( _T( "DISAUserChannel::NotifyConnectionStatusDfc 0x%x <-" ), chPtr->iChannelNumber ) ); + + OstTraceExt1( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_CONNECTIONSTATUSDFC_EXIT, "iChannelNumber=%hx", chPtr->iChannelNumber ); + } + +void DISAUserChannel::NotifyFlowCtrl( + TIADFlowControlStatus aStatus + ) + { + + OstTraceExt3( TRACE_NORMAL, DISAUSERCHANNEL_NOTIFYFLOWCTRL_ENTRY, "DISAUserChannel::NotifyFlowCtrl;aStatus=%x;iChannelNumber=%hx;iFlowCtrlStatus=%d", ( TUint )( aStatus ), iChannelNumber, iFlowCtrlStatus ); + C_TRACE( ( _T( "DISAUserChannel::NotifyFlowCtrl 0x%x %d > %d ->" ), iChannelNumber, iFlowCtrlStatus, aStatus ) ); + // Atomic STR no need to synch. + iFlowCtrlStatus = aStatus; + TRACE_WARNING( !iFlowCtrlStatusDfc->Queued(), iChannelNumber ); + iFlowCtrlStatusDfc->Enque(); + C_TRACE( ( _T( "DISAUserChannel::NotifyFlowCtrl 0x%x %d %d <-" ), iChannelNumber, iFlowCtrlStatus, aStatus ) ); + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_NOTIFYFLOWCTRL_EXIT, "DISAUserChannel::FlowCtrlStatusDfc;aPtr=%x", ( TUint )( aPtr ) ); + DISAUserChannel* chPtr = reinterpret_cast( aPtr ); + C_TRACE( ( _T( "DISAUserChannel::FlowCtrlStatusDfc 0x%x ->" ), chPtr->iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DISAUSERCHANNEL_FLOWCTRLSTATUSDFC, "DISAUserChannel::FlowCtrlStatusDfc;chPtr->iChannelNumber=%hx", chPtr->iChannelNumber ); + ASSERT_DFCTHREAD_INLDD(); + if( chPtr->iIADFlowControlStatusPtr && + ( chPtr->iLastNotifiedFlowCtrlStatus != chPtr->iFlowCtrlStatus ) ) + { + TIADReq req( EIADAsyncNotifyFlowControlStatus, KErrNone ); + if( chPtr->iReqQueue->Add( req ) ) + { + TInt temp( chPtr->iFlowCtrlStatus ); + C_TRACE( ( _T( "DISAUserChannel::FlowCtrlStatusDfc 0x%x request active, writing %d" ), chPtr->iChannelNumber, temp ) ); + OstTraceExt2( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_FLOWCTRLSTATUSDFC, "DISAUserChannel::FlowCtrlStatusDfc;chPtr->iChannelNumber=%hx;writing iFlowCtrlStatus=%d", chPtr->iChannelNumber, temp ); + + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadRawWrite( chPtr->iThread, chPtr->iIADFlowControlStatusPtr, &temp, sizeof(TUint16), chPtr->iThread ), + EIADDesWriteFailed | ( TUint8 )( chPtr->iChannelNumber ) << KChannelNumberShift | EIADFaultIdentifier2 << KFaultIdentifierShift ); + TRACE_ASSERT( !chPtr->iCompleteChannelRequestDfc->Queued() ); + CompleteChReqDfc( chPtr ); + chPtr->iLastNotifiedFlowCtrlStatus = temp; + } + } + C_TRACE( ( _T( "DISAUserChannel::FlowCtrlStatusDfc 0x%x <-" ), chPtr->iChannelNumber ) ); + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_FLOWCTRLSTATUSDFC_EXIT, "" ) ) ); + ASSERT_CONTEXT_ALWAYS( NKern::EThread, 0 ); + iDataRx->Add( aDataMessage ); + iEmptyDataRxQueueDfc->Enque(); + C_TRACE( ( _T( "DISAUserChannel::ReceiveDataMsg <-" ) ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_RECEIVEDATAMSG_EXIT, "DISAUserChannel::ReceiveMsg;aMessage=%x;iChannelNumber=%hx", ( TUint )&( aMessage ), iChannelNumber ); + + C_TRACE( ( _T( "DISAUserChannel::ReceiveMsg 0x%x 0x%x ->" ), &aMessage, iChannelNumber ) ); + // Can only be called from thread context. + ASSERT_CONTEXT_ALWAYS( NKern::EThread, 0 ); + iRx->Add( aMessage ); + iEmptyRxQueueDfc->Enque(); + C_TRACE( ( _T( "DISAUserChannel::ReceiveMsg 0x%x 0x%x <-" ), &aMessage, iChannelNumber ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_RECEIVEMSG_EXIT, "DISAUserChannel::RegisterPep;aPep=%x;iChannelNumber=%hx", ( TUint )&( aPep ), iChannelNumber ); + + C_TRACE( ( _T( "DISAUserChannel::RegisterPep 0x%x 0x%x ->" ), iPep, iChannelNumber ) ); + iPep = &aPep; + C_TRACE( ( _T( "DISAUserChannel::RegisterPep 0x%x 0x%x <-" ), iPep, iChannelNumber ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_REGISTERPEP, "DISAUserChannel::EmptyRxQueueDfc;aPtr=%x", ( TUint )( aPtr ) ); + + ASSERT_DFCTHREAD_INLDD(); + DISAUserChannel& chTmp = *reinterpret_cast( aPtr ); + C_TRACE( ( _T( "DISAUserChannel::EmptyRxQueueDfc 0x%x ->" ), chTmp.iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DISAUSERCHANNEL_EMPTYRXQUEUEDFC, "DISAUserChannel::EmptyRxQueueDfc;iChannelNumber=%hx", chTmp.iChannelNumber ); + + if( ( chTmp.iReqQueue->GetReq( EIADAsyncReceive ) ) && ( chTmp.iRx->Count() > 0 ) ) + { + TDes8& tmpDes = chTmp.iRx->Get(); + TInt desMaxLen( Kern::ThreadGetDesMaxLength( chTmp.iThread, chTmp.iReceiveBufPtr ) ); + // If user descriptor legth is enough and length get not failed. + if( desMaxLen >= tmpDes.Length() ) + { + // Write to user address space (iReceiveBufPtr) the content of tmpDes starting from zero offset as 8bit descriptor data. + TInt writeError( Kern::ThreadDesWrite( chTmp.iThread, chTmp.iReceiveBufPtr, tmpDes, KDestStartOffset, KChunkShiftBy0, chTmp.iThread ) ); + if( writeError == KErrNone ) + { + C_TRACE( ( _T( "DISAUserChannel::EmptyRxQueueDfc write 0x%x k->u 0x%x ok 0x%x" ), &tmpDes, chTmp.iReceiveBufPtr, chTmp.iChannelNumber ) ); + OstTraceExt3( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_EMPTYRXQUEUEDFC, "DISAUserChannel::EmptyRxQueueDfc write ok;src=%x;dest=%x;iChannelNumber=%hx", (TUint)&(tmpDes), (TUint)(chTmp.iReceiveBufPtr), chTmp.iChannelNumber ); + + TIADReq req( static_cast( EIADAsyncReceive ), writeError ); + if( chTmp.iReqQueue->Add( req ) ) + { + TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() ); + CompleteChReqDfc( &chTmp ); + } + chTmp.iRxDeAllocate->Add( tmpDes ); + chTmp.iCleanDfc->Enque();// If same prio in ldd & extension dfc threads ok, scheduled after this dfc run and now context switch happens from ldd->ext->ldd + } + // Write unsuccesfull don't deallocate the block. + else + { + C_TRACE( ( _T( "DISAUserChannel::EmptyRxQueueDfc write 0x%x k->u 0x%x NOK, reason %d 0x%x" ), &tmpDes, chTmp.iReceiveBufPtr, writeError, chTmp.iChannelNumber ) ); + OstTraceExt4( TRACE_NORMAL, DISAUSERCHANNEL_EMPTYRXQUEUEDFC_WRITE_FAIL, "DISAUserChannel::EmptyRxQueueDfc write fail;src=%x;dest=%x;writeError=%d;iChannelNumber=%hx", (TUint)&(tmpDes), (TUint)(chTmp.iReceiveBufPtr), writeError, chTmp.iChannelNumber ); + + TRACE_ASSERT_INFO( 0, ( TUint8 )( chTmp.iChannelNumber ) << KChannelNumberShift | (TUint16)writeError ); + // Roll the message back to que. + chTmp.iRx->RollBack( tmpDes ); + TIADReq req( static_cast( EIADAsyncReceive ), writeError ); + if( chTmp.iReqQueue->Add( req ) ) + { + TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() ); + CompleteChReqDfc( &chTmp ); + } + } + } + // If descriptor invalid. + else + { + TRACE_WARNING( 0, (TUint8)chTmp.iChannelNumber << KChannelNumberShift | (TUint16)tmpDes.Length() ); + // Roll the message back to que. + chTmp.iRx->RollBack( tmpDes ); + // If invalid content. + if( KErrBadDescriptor == desMaxLen ) + { + TRACE_ASSERT_INFO( 0, (TUint8)chTmp.iChannelNumber << KChannelNumberShift | (TUint16)desMaxLen ); + C_TRACE( ( _T( "DISAUserChannel::EmptyRxQueueDfc invalid descriptor 0x%x" ), chTmp.iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DUP2_DISAUSERCHANNEL_EMPTYRXQUEUEDFC, "DISAUserChannel::EmptyRxQueueDfc KErrBadDescriptor;iChannelNumber=%hx", chTmp.iChannelNumber ); + TIADReq req( static_cast( EIADAsyncReceive ), KErrBadDescriptor ); + if( chTmp.iReqQueue->Add( req ) ) + { + TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() ); + CompleteChReqDfc( &chTmp ); + } + } + // If length too small (if other assert). + else + { + TUint16 neededLength( tmpDes.Length() ); + TRACE_WARNING( 0, (TUint8)chTmp.iChannelNumber << KChannelNumberShift | (TUint16)desMaxLen ); + C_TRACE( ( _T( "DISAUserChannel::EmptyRxQueueDfc descriptor length too small length %d needed %d 0x%x" ), desMaxLen, neededLength, chTmp.iChannelNumber ) ); + OstTraceExt3( TRACE_NORMAL, DUP3_DISAUSERCHANNEL_EMPTYRXQUEUEDFC, "DISAUserChannel::EmptyRxQueueDfc too small length;desMaxLen=%d;neededLength=%hu;iChannelNumber=%hx", desMaxLen, neededLength, chTmp.iChannelNumber ); + + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadRawWrite( chTmp.iThread, chTmp.iNeededBufLen, &neededLength, sizeof(TUint16), chTmp.iThread ), + EIADDesWriteFailed | ( TUint8 )( chTmp.iChannelNumber ) << KChannelNumberShift | EIADFaultIdentifier3 << KFaultIdentifierShift ); + TIADReq req( static_cast( EIADAsyncReceive ), KErrNoMemory ); + if( chTmp.iReqQueue->Add( req ) ) + { + TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() ); + CompleteChReqDfc( &chTmp ); + } + } + } + } + else + { + C_TRACE( ( _T( "DISAUserChannel::EmptyRxQueueDfc 0x%x no receive active or no message" ), chTmp.iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DUP4_DISAUSERCHANNEL_EMPTYRXQUEUEDFC, "DISAUserChannel::EmptyRxQueueDfc no receive active or no message;iChannelNumber=%hx", chTmp.iChannelNumber ); + + } + C_TRACE( ( _T( "DISAUserChannel::EmptyRxQueueDfc 0x%x <-" ), chTmp.iChannelNumber ) ); + + OstTraceExt1( TRACE_NORMAL, DISAUSERCHANNEL_EMPTYRXQUEUEDFC_EXIT, "( aPtr ); + C_TRACE( ( _T( "DISAUserChannel::CleanBlocksDfc 0x%x ->" ), chTmp->iChannelNumber ) ); + while( chTmp->iRxDeAllocate->Count() > 0 ) + { + TDes8& blockToDeAllocate = chTmp->iRxDeAllocate->Get(); + C_TRACE( ( _T( "DISAUserChannel::CleanBlocksDfc dealloc 0x%x" ), &blockToDeAllocate ) ); + OstTraceExt2( TRACE_NORMAL, DISAUSERCHANNEL_CLEANBLOCKSDFC, "DISAUserChannel::CleanBlocksDfc;blockToDeAllocate=%x;iChannelNumber=%hx", (TUint)&(blockToDeAllocate), chTmp->iChannelNumber ); + + + chTmp->iExtensionApi->DeAllocateBlock( blockToDeAllocate ); + } + C_TRACE( ( _T( "DISAUserChannel::CleanBlocksDfc 0x%x <-" ), chTmp->iChannelNumber ) ); + + OstTraceExt1( TRACE_NORMAL, DISAUSERCHANNEL_CLEANBLOCKSDFC_EXIT, "iChannelNumber ); + } + +void DISAUserChannel::CleanDataBlocksDfc( + TAny* aPtr // Pointer to self + ) + { + OstTrace1( TRACE_NORMAL, DISAUSERCHANNEL_CLEANDATABLOCKSDFC_ENTRY, ">DISAUserChannel::CleanDataBlocksDfc;aPtr=%x", ( TUint )( aPtr ) ); + + DISAUserChannel* chTmp = reinterpret_cast( aPtr ); + C_TRACE( ( _T( "DISAUserChannel::CleanDataBlocksDfc 0x%x ->" ), chTmp->iChannelNumber ) ); + while( chTmp->iDataRxDeAllocate->Count() > 0 ) + { + TDes8& blockToDeAllocate = chTmp->iDataRxDeAllocate->Get(); + C_TRACE( ( _T( "DISAUserChannel::CleanDataBlocksDfc dealloc 0x%x" ), &blockToDeAllocate ) ); + OstTraceExt2( TRACE_NORMAL, DISAUSERCHANNEL_CLEANDATABLOCKSDFC, "DISAUserChannel::CleanDataBlocksDfc;blockToDeAllocate=%x;iChannelNumber=%hx", (TUint)&(blockToDeAllocate), chTmp->iChannelNumber ); + + chTmp->iExtensionApi->DeAllocateBlock( blockToDeAllocate ); + ASSERT_RESET_ALWAYS( chTmp->iPep, EIADNullParameter | EIADFaultIdentifier31 << KFaultIdentifierShift ); + chTmp->iPep->DataMessageDelivered(); + } + C_TRACE( ( _T( "DISAUserChannel::CleanDataBlocksDfc 0x%x <-" ), chTmp->iChannelNumber ) ); + + OstTraceExt1( TRACE_NORMAL, DISAUSERCHANNEL_CLEANDATABLOCKSDFC_EXIT, "iChannelNumber); + } + +void DISAUserChannel::EmptyDataRxQueueDfc( + TAny* aPtr // Pointer to self + ) + { + OstTrace1( TRACE_NORMAL, DISAUSERCHANNEL_EMPTYDATARXQUEUEDFC_ENTRY, "DISAUserChannel::EmptyDataRxQueueDfc;aPtr=%x", ( TUint )( aPtr ) ); + + ASSERT_DFCTHREAD_INLDD(); + DISAUserChannel& chTmp = *reinterpret_cast( aPtr ); + C_TRACE( ( _T( "DISAUserChannel::EmptyDataRxQueueDfc 0x%x ->" ), chTmp.iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DISAUSERCHANNEL_EMPTYDATARXQUEUEDFC, "DISAUserChannel::EmptyDataRxQueueDfc;iChannelNumber=%hx", chTmp.iChannelNumber ); + + if( ( chTmp.iReqQueue->GetReq( EIADAsyncDataReceive ) ) && ( chTmp.iDataRx->Count() > 0 ) ) + { + TDes8& tmpDes = chTmp.iDataRx->Get(); + TInt tmpLength( tmpDes.Length() - KPipeDataHeader ); + C_TRACE( ( _T( "DISAUserChannel::EmptyDataRxQueueDfc tmpDes %d %d %d" ), tmpDes.Length(), tmpLength, tmpDes.MaxLength() ) ); + OstTraceExt3( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_EMPTYDATARXQUEUEDFC, "DISAUserChannel::EmptyDataRxQueueDfc;srcLength()=%d;srcCopyLength=%d;srcMaxLength()=%d", tmpDes.Length(), tmpLength, tmpDes.MaxLength() ); + TInt desMaxLen( Kern::ThreadGetDesMaxLength( chTmp.iThread, chTmp.iDataReceiveBufPtr ) ); + // If user descriptor legth is enough and length get not failed. + if( desMaxLen >= tmpLength ) + { + if ( ( chTmp.iChannelNumber == EIscNokiaNifPep0 || + chTmp.iChannelNumber == EIscNokiaNifPep1 || + chTmp.iChannelNumber == EIscNokiaNifPep2 || + chTmp.iChannelNumber == EIscNokiaNifPep3 || + chTmp.iChannelNumber == EIscNokiaNifPep4 || + chTmp.iChannelNumber == EIscNokiaNifPep5 || + chTmp.iChannelNumber == EIscNokiaNifPep6 || + chTmp.iChannelNumber == EIscNokiaNifPep7 || + chTmp.iChannelNumber == EIscNokiaNifPep8 || + chTmp.iChannelNumber == EIscNokiaNifPep9 || + chTmp.iChannelNumber == EIscNokiaNifPep10 ) && + ( tmpLength > 1500 ) ) + { + TInt fault_code = 0; + fault_code = fault_code | (TUint16)(chTmp.iChannelNumber); + fault_code = fault_code << 16; + fault_code = fault_code | (TUint16)(tmpLength); + Kern::Fault("FATAL ERROR: Nif length over 1500 bytes [chn][len]", fault_code); + } + + TUint8* tmpPtr( const_cast( tmpDes.Ptr() + KPipeDataHeader ) ); + TPtr8 tmp( tmpPtr, tmpLength, tmpLength ); + TInt writeError( Kern::ThreadDesWrite( chTmp.iThread, chTmp.iDataReceiveBufPtr, tmp, KDestStartOffset, KChunkShiftBy0, chTmp.iThread ) ); + if( writeError == KErrNone ) + { + C_TRACE( ( _T( "DISAUserChannel::EmptyDataRxQueueDfc write 0x%x k->u 0x%x ok 0x%x" ), &tmpDes, chTmp.iDataReceiveBufPtr, chTmp.iChannelNumber ) ); + OstTraceExt3( TRACE_NORMAL, DISAUSERCHANNEL_EMPTYDATARXQUEUEDFC__WRITE_OK, "DISAUserChannel::EmptyDataRxQueueDfc write ok;src=%x;dest=%x;iChannelNumber=%hx", (TUint)&tmpDes, (TUint)chTmp.iDataReceiveBufPtr, chTmp.iChannelNumber ); + TIADReq req( static_cast( EIADAsyncDataReceive ), writeError ); + if( chTmp.iReqQueue->Add( req ) ) + { + TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() ); + CompleteChReqDfc( &chTmp ); + } + chTmp.iDataRxDeAllocate->Add( tmpDes ); + if( chTmp.iDataRx->Count() == 0 ) + { + chTmp.iCleanDataDfc->Enque();// If same prio in ldd & extension dfc threads ok, scheduled after this dfc run and now context switch happens from ldd->ext->ldd + } + } + // Write unsuccesfull don't deallocate the block. + else + { + C_TRACE( ( _T( "DISAUserChannel::EmptyDataRxQueueDfc write 0x%x k->u 0x%x NOK, reason %d 0x%x" ), &tmpDes, chTmp.iDataReceiveBufPtr, writeError, chTmp.iChannelNumber ) ); + OstTraceExt4( TRACE_NORMAL, DISAUSERCHANNEL_EMPTYDATARXQUEUEDFC_WRITE_FAIL, "DISAUserChannel::EmptyDataRxQueueDfc;src=%x;dest=%x;writeError=%d;iChannelNumber=%hx", (TUint)&tmpDes, (TUint)chTmp.iDataReceiveBufPtr, writeError, chTmp.iChannelNumber ); + TRACE_ASSERT_INFO( 0, ( TUint8 )( chTmp.iChannelNumber ) << KChannelNumberShift | (TUint16)tmpLength ); + // Roll the message back to que. + chTmp.iDataRx->RollBack( tmpDes ); + TIADReq req( static_cast( EIADAsyncDataReceive ), writeError ); + if( chTmp.iReqQueue->Add( req ) ) + { + TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() ); + CompleteChReqDfc( &chTmp ); + } + } + } + // If descriptor invalid. + else + { + TRACE_WARNING( 0, (TUint8)chTmp.iChannelNumber << KChannelNumberShift | (TUint16)tmpLength ); + // Roll the message back to que. + chTmp.iDataRx->RollBack( tmpDes ); + // If invalid content. + if( KErrBadDescriptor == desMaxLen ) + { + TRACE_ASSERT_INFO( 0, (TUint8)chTmp.iChannelNumber << KChannelNumberShift ); + C_TRACE( ( _T( "DISAUserChannel::EmptyDataRxQueueDfc invalid descriptor 0x%x" ), chTmp.iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DUP2_DISAUSERCHANNEL_EMPTYDATARXQUEUEDFC, "DISAUserChannel::EmptyDataRxQueueDfc invalid descriptor;iChannelNumber=%hx", chTmp.iChannelNumber ); + + // CHANGE: call now straight a way in LDD thread context the complete without enqueing the dfc function inbetween. + TIADReq req( static_cast( EIADAsyncDataReceive ), KErrBadDescriptor ); + if( chTmp.iReqQueue->Add( req ) ) + { + TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() ); + CompleteChReqDfc( &chTmp ); + } + } + // If length too small (if other assert). + else + { + TUint16 neededLength( tmpLength ); + TRACE_WARNING( 0, (TUint8)chTmp.iChannelNumber << KChannelNumberShift | (TUint16)desMaxLen ); + C_TRACE( ( _T( "DISAUserChannel::EmptyDataRxQueueDfc descriptor length too small length %d needed %d 0x%x" ), desMaxLen, neededLength, chTmp.iChannelNumber ) ); + OstTraceExt3( TRACE_NORMAL, DUP3_DISAUSERCHANNEL_EMPTYDATARXQUEUEDFC, "DISAUserChannel::EmptyDataRxQueueDfc descriptor length too small;desMaxLen=%d;neededLength=%hu;iChannelNumber=%hx", desMaxLen, neededLength, chTmp.iChannelNumber ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadRawWrite( chTmp.iThread, chTmp.iNeededDataBufLen, &neededLength, sizeof(TUint16), chTmp.iThread ), + EIADDesWriteFailed | ( TUint8 )( chTmp.iChannelNumber ) << KChannelNumberShift | EIADFaultIdentifier4 << KFaultIdentifierShift ); + TIADReq req( static_cast( EIADAsyncDataReceive ), KErrNoMemory ); + if( chTmp.iReqQueue->Add( req ) ) + { + TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() ); + CompleteChReqDfc( &chTmp ); + } + } + } + } + else + { + C_TRACE( ( _T( "DISAUserChannel::EmptyDataRxQueueDfc 0x%x no datareceive active or no message" ), chTmp.iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DUP4_DISAUSERCHANNEL_EMPTYDATARXQUEUEDFC, "DISAUserChannel::EmptyDataRxQueueDfc no datareceive active or no message;iChannelNumber=%hx", chTmp.iChannelNumber ); + } + C_TRACE( ( _T( "DISAUserChannel::EmptyDataRxQueueDfc 0x%x <-" ), chTmp.iChannelNumber ) ); + OstTraceExt1( TRACE_NORMAL, DISAUSERCHANNEL_EMPTYDATARXQUEUEDFC_EXIT, "DISAUserChannel::ResetQueues;iChannelNumber=%hx", iChannelNumber ); + C_TRACE( ( _T( "DISAUserChannel::ResetQueues 0x%x ->" ), iChannelNumber ) ); + OstTraceExt3( TRACE_NORMAL, DISAUSERCHANNEL_RESETQUEUES, "DISAUserChannel::ResetQueues Rx;iChannelNumber=%hx;iRx=%x;iDataRx=%x", iChannelNumber, (TUint)iRx, (TUint)iDataRx ); + if( iRx ) + { + C_TRACE( ( _T( "DISAUserChannel::ResetQueues 0x%x iRx 0x%x" ), iChannelNumber, iRx ) ); + while( iRx->Count() ) + { + iExtensionApi->DeAllocateBlock( iRx->Get() ); + } + } + if( iDataRx ) + { + C_TRACE( ( _T( "DISAUserChannel::ResetQueues 0x%x iDataRx 0x%x" ), iChannelNumber, iDataRx ) ); + while( iDataRx->Count() ) + { + iExtensionApi->DeAllocateBlock( iDataRx->Get() ); + } + } + //PERF + if( iRxDeAllocate ) + { + C_TRACE( ( _T( "DISAUserChannel::ResetQueues 0x%x iRxDeAllocate 0x%x" ), iChannelNumber, iDataRx ) ); + while( iRxDeAllocate->Count() ) + { + iExtensionApi->DeAllocateBlock( iRxDeAllocate->Get() ); + } + } + //PERF + //PERF + if( iDataRxDeAllocate ) + { + C_TRACE( ( _T( "DISAUserChannel::ResetQueues 0x%x iDataRxDeAllocate 0x%x" ), iChannelNumber, iDataRx ) ); + while( iDataRxDeAllocate->Count() ) + { + iExtensionApi->DeAllocateBlock( iDataRxDeAllocate->Get() ); + } + } + //PERF + + C_TRACE( ( _T( "DISAUserChannel::ResetQueues 0x%x <-" ), iChannelNumber ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_RESETQUEUES_EXIT, "" ) ) ); + ASSERT_CONTEXT_ALWAYS( NKern::EThread, 0 ); + TUint32* tablePtr = reinterpret_cast( a1 ); + TRACE_ASSERT_INFO( tablePtr[ KFirstParam ], (TUint16)aRequest ); + TRequestStatus* requestStatus = reinterpret_cast( tablePtr[ KFirstParam ] ); + // If request already active. + if( ( iReqQueue->GetReq( static_cast< TIADAsyncRequest >( aRequest ) ) ) ) + { + // Fault if request is already pending and the request status pointer is different. + // Fault prints 0-7bits: request, 8-15bits: ch number, 16-31bits: fault identifier + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest Channel 0x%x setting request %d active twice, illegal" ), iChannelNumber, aRequest ) ); + OstTraceExt2( TRACE_NORMAL, DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest double request;iChannelNumber=%hx;aRequest=%d", iChannelNumber, aRequest ); + + // Assert cause request already active. + TRACE_ASSERT_INFO( 0, ( EIADSameRequestTwice | static_cast( iChannelNumber ) << KChannelNumberShift | static_cast( aRequest ) << KExtraInfoShift ) ); + // Active object should not give same request object twice before completing the first one. + ASSERT_PANIC_USER_THREAD_ALWAYS( iReqQueue->GetReq( static_cast< TIADAsyncRequest >( aRequest ) ) == requestStatus, iThread, + ( EIADSameRequestTwice | static_cast( iChannelNumber ) << KChannelNumberShift | static_cast( aRequest ) << KExtraInfoShift ) ); + ////////////////// NOTE!!! CHANGE TO API SPECIFICATION !!!!!!!!!!!!!!!!! ////////////////////////// + ////////////////// PREVIOUSLY KErrAlreadyExists was returned !!!!!!!!!!!!!!!!! ////////////////////////// + } + else + { + iReqQueue->SetReq( static_cast< TIADAsyncRequest >( aRequest ), requestStatus ); + switch ( aRequest ) + { + case EIADAsyncOpen: + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncOpen" ) ) ); + OstTrace0( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncOpen" ); + + iIADUserChannelNumberPtr = reinterpret_cast( tablePtr[ KSecondParam ] ); + TAny* thirdParam = reinterpret_cast( tablePtr[ KThirdParam ] ); + // If resource used, if not length is zero. + TInt openInfoLength = Kern::ThreadGetDesLength( iThread, thirdParam ); + // Resource used in channel opening. + if( openInfoLength > 0 ) + { + C_TRACE( ( _T( "DIscChannel::HandleAsyncRequest EIADAsyncOpen resource" ) ) ); + // In channel opening we can use dynamic allocation no speed requirements for open. + OstTrace0( TRACE_NORMAL, DUP2_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncOpen resource" ); + TUint8* buffer = reinterpret_cast( Kern::Alloc( openInfoLength ) ); + TPtr8* bufferPtr = new TPtr8( buffer, openInfoLength ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, thirdParam, *bufferPtr, 0, KChunkShiftBy0 ), EIADDesReadFailed | EIADFaultIdentifier1 << KFaultIdentifierShift ); + // Must be called in extension context. + iExtensionApi->Open( ~iChannelNumber, aRequest, *bufferPtr, this ); + Kern::Free( buffer ); + delete bufferPtr; + bufferPtr = NULL; + } + // Resource not used in channel opening. + else + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncOpen normal" ) ) ); + // Must be called in extension context. + iExtensionApi->Open( ~iChannelNumber, aRequest, this ); + } + break; + } + case EIADAsyncClose: + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncClose" ) ) ); + OstTraceExt1( TRACE_NORMAL, DUP3_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncClose;iChannelNumber=%hx", iChannelNumber ); + + ResetQueues(); + if( KNotInitializedChannel != iChannelNumber ) + { + // Cancel any outstanding request. + // Remember in asynch close not to cancel it when closing. + for( TInt i( 0 ); i < EIADAsyncLast; ++i ) + { + if( iReqQueue->GetReq( static_cast< TIADAsyncRequest >( i ) ) && EIADAsyncClose != i ) + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncClose req to cancel %d" ), i ) ); + OstTraceExt1( TRACE_NORMAL, DUP17_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncClose;ReqToCancel=%hx", i ); + + DoCancel( KMaxTInt, i ); + } + } + // Must be called in extension context. + iExtensionApi->Close( iChannelNumber ); + } + CompleteChannelRequest( EIADAsyncClose, KErrNone ); + break; + } + case EIADAsyncReceive: + { + iReceiveBufPtr = reinterpret_cast( tablePtr[ KSecondParam ] ); + iNeededBufLen = reinterpret_cast( tablePtr[ KThirdParam ] ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncReceive 0x%x 0x%x" ), iNeededBufLen, iReceiveBufPtr ) ); + OstTraceExt2( TRACE_NORMAL, DUP4_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncReceive;iNeededBufLen=%x;iReceiveBufPtr=%x", (TUint)iNeededBufLen, (TUint)iReceiveBufPtr ); + iEmptyRxQueueDfc->Enque(); + break; + } + case EIADAsyncNotifyConnectionStatus: + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncNotifyConnectionStatus" ) ) ); + iIADConnectionStatusPtr = reinterpret_cast( tablePtr[ KSecondParam ] ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncNotifyConnectionStatus TBR 0x%x" ), iIADConnectionStatusPtr ) ); + OstTrace1( TRACE_NORMAL, DUP5_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncNotifyConnectionStatus;iIADConnectionStatusPtr=%x", iIADConnectionStatusPtr ); + break; + } + case EIADAsyncDataReceive: + { + iDataReceiveBufPtr = reinterpret_cast( tablePtr[ KSecondParam ] ); + iNeededDataBufLen = reinterpret_cast( tablePtr[ KThirdParam ] ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncDataReceive 0x%x 0x%x" ), iNeededDataBufLen, iDataReceiveBufPtr ) ); + OstTraceExt2( TRACE_NORMAL, DUP7_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncDataReceive;iNeededDataBufLen=%x;iDataReceiveBufPtr=%x", (TUint)iNeededDataBufLen, (TUint)iDataReceiveBufPtr ); + iEmptyDataRxQueueDfc->Enque(); + break; + } + case EIADAsyncNotifyFlowControlStatus: + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncNotifyFlowControlStatus" ) ) ); + iIADFlowControlStatusPtr = reinterpret_cast( tablePtr[ KSecondParam ] ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncNotifyFlowControlStatus TBR 0x%x" ), iIADFlowControlStatusPtr ) ); + OstTrace1( TRACE_NORMAL, DUP8_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncNotifyFlowControlStatus;iIADFlowControlStatusPtr=%x", iIADFlowControlStatusPtr ); + + if ( iLastNotifiedFlowCtrlStatus != iFlowCtrlStatus ) + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest iFlowCtrlStatus changed!" ) ) ); + OstTraceExt2( TRACE_NORMAL, DUP6_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest flow control status changed;iLastNotifiedFlowCtrlStatus=%d;iFlowCtrlStatus=%d", iLastNotifiedFlowCtrlStatus, iFlowCtrlStatus ); + + TRACE_ASSERT( !iFlowCtrlStatusDfc->Queued() ); + iFlowCtrlStatusDfc->Enque(); + } + break; + } + case EIADAsyncSend: + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncSend" ) ) ); + TUint32* tablePtr = reinterpret_cast( a1 ); + TAny* secondParam = reinterpret_cast( tablePtr[ KSecondParam ] ); + ASSERT_RESET_ALWAYS( secondParam, EIADNullParameter | EIADFaultIdentifier23 << KFaultIdentifierShift ); + TInt msgLength( Kern::ThreadGetDesLength( iThread, secondParam ) ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncSend 0x%x %d" ), secondParam, msgLength ) ); + OstTraceExt2( TRACE_NORMAL, DUP10_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncSend;secondParam=%x;msgLength=%d", (TUint)secondParam, msgLength ); + + TInt error( KErrBadDescriptor ); + if( msgLength > 0 ) + { + // Previously there were Kern::Alloc (allocating from kernel memory a block where copy from user was made no only + // one copy from user to allocated block that is to be send. + TDes8& sendBlock = iExtensionApi->AllocateBlock( msgLength ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, secondParam, sendBlock, 0, KChunkShiftBy0 ), EIADDesReadFailed | EIADFaultIdentifier2 << KFaultIdentifierShift ); + TRACE_ASSERT_INFO( sendBlock.Length() == msgLength, (TUint8)iChannelNumber << KChannelNumberShift ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncSend 0x%x 0x%x" ), &sendBlock, iChannelNumber ) ); + OstTraceExt2( TRACE_NORMAL, DUP16_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncSend;sendBlock=%x;iChannelNumber=%hx", (TUint)&sendBlock, iChannelNumber ); + + error = iExtensionApi->SendMessage( sendBlock, iChannelNumber ); + } + else + { + error = ( msgLength == KErrNone ) ? KErrBadDescriptor : msgLength; + TRACE_ASSERT_INFO( 0, (TUint8)iChannelNumber << KChannelNumberShift | (TUint16)msgLength ); + } + CompleteChannelRequest( aRequest, error ); + break; + } + case EIADAsyncDataSend: + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncDataSend" ) ) ); + TUint32* tablePtr = reinterpret_cast( a1 ); + TAny* secondParam = reinterpret_cast( tablePtr[ KSecondParam ] ); + ASSERT_RESET_ALWAYS( secondParam, EIADNullParameter | EIADFaultIdentifier24 << KFaultIdentifierShift ); + TInt msgLength( Kern::ThreadGetDesLength( iThread, secondParam ) ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADAsyncDataSend 0x%x %d" ), secondParam, msgLength ) ); + OstTraceExt2( TRACE_NORMAL, DUP9_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncDataSend;secondParam=%x;msgLength=%d", (TUint)secondParam, msgLength ); + TInt error( KErrBadDescriptor ); + if( msgLength > KErrNone ) + { + // Allocate a block for data. Allocation adds +11 to the msglength for pipe headers + TDes8& sendBlock = iExtensionApi->AllocateDataBlock( msgLength ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncDataSend max %d length %d" ), sendBlock.MaxLength(), sendBlock.Length() ) ); + // Use pre-allocated TPtr (no memory allocation from heap nor stack). + // Set it to point to +11 from sendblock and to be as long as data to be send + TInt tmpMaxLength( sendBlock.MaxLength() - KPipeDataHeader ); + TUint8* tmpPtr( const_cast( ( sendBlock.Ptr() + KPipeDataHeader ) ) ); + TPtr* test = static_cast( &sendBlock ); + test->Set( tmpPtr, 0, tmpMaxLength ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, secondParam, *test, 0, KChunkShiftBy0 ), EIADDesReadFailed | EIADFaultIdentifier3 << KFaultIdentifierShift ); + TInt tmpMaxLength2( sendBlock.MaxLength() + KPipeDataHeader ); + TInt tmpLength2( sendBlock.Length() + KPipeDataHeader ); + TUint8* tmpPtr2( const_cast( ( sendBlock.Ptr() - KPipeDataHeader ) ) ); + test->Set( tmpPtr2, tmpLength2, tmpMaxLength2 ); + TRACE_ASSERT_INFO( sendBlock.Length() > msgLength, (TUint8)iChannelNumber << KChannelNumberShift ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncDataSend 0x%x 0x%x" ), &sendBlock, iChannelNumber ) ); + OstTraceExt4( TRACE_NORMAL, DUP15_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncDataSend;sendBlock=%x;sendBlock.MaxLength()=%d;sendBlock.Length()=%d;iChannelNumber=%hx", (TUint)&sendBlock, sendBlock.MaxLength(), sendBlock.Length(), iChannelNumber ); + + error = iExtensionApi->SendMessage( sendBlock, iChannelNumber ); + } + else + { + error = ( msgLength == KErrNone ) ? KErrBadDescriptor : msgLength; + TRACE_ASSERT_INFO( 0, (TUint8)iChannelNumber << KChannelNumberShift | (TUint16)msgLength ); + } + CompleteChannelRequest( aRequest, error ); + break; + } + case EIADAsyncSubscribeIndications: + case EIADAsyncSubscribeIndications32Bit: + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncSubscribeIndications | EIADAsyncSubscribeIndications32Bit" ) ) ); + TUint32* tablePtr = reinterpret_cast( a1 ); + TAny* secondParam = reinterpret_cast(tablePtr[ KSecondParam ]); + ASSERT_RESET_ALWAYS( secondParam, EIADNullParameter | EIADFaultIdentifier25 << KFaultIdentifierShift ); + TInt orderLength( Kern::ThreadGetDesLength( iThread, secondParam ) ); + C_TRACE( ( _T( "DISAUserChannel::DISAUserChannel::HandleAsyncRequest EIADAsyncSubscribeIndications | EIADAsyncSubscribeIndications32Bit 0x%x %d" ), secondParam, orderLength ) ); + OstTraceExt2( TRACE_NORMAL, DUP12_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncSubscribeIndications(8/32bit);secondParam=%x;orderLength=%d", (TUint)secondParam, orderLength ); + + TInt error( KErrBadDescriptor ); + if( orderLength > 0 ) + { + // Previously there were Kern::Alloc (allocating from kernel memory a block where copy from user was made no only + // one copy from user to allocated block that is to be send. + TDes8& sendBlock = iExtensionApi->AllocateBlock( ( orderLength ) ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, secondParam, sendBlock, 0, KChunkShiftBy0 ), EIADDesReadFailed | EIADFaultIdentifier4 << KFaultIdentifierShift ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncSubscribeIndications | EIADAsyncSubscribeIndications32Bit 0x%x 0x%x" ), &sendBlock, iChannelNumber ) ); + OstTraceExt2( TRACE_NORMAL, DUP14_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncSubscribeIndications(8/32bit);sendBlock=%x;iChannelNumber=%hx", (TUint)&sendBlock, iChannelNumber ); + + TRACE_ASSERT_INFO( sendBlock.Length() == orderLength, (TUint8)iChannelNumber << KChannelNumberShift ); + // No return values check needed. Request completed with error value by multiplexer + TBool thirtyTwoBit( ( EIADSubscribeIndications32Bit == aRequest ) ? ETrue : EFalse ); + error = iExtensionApi->OrderIndication( sendBlock, iChannelNumber, thirtyTwoBit ); + iExtensionApi->DeAllocateBlock( sendBlock ); + } + else + { + error = orderLength; + TRACE_ASSERT_INFO( 0, (TUint8)iChannelNumber << KChannelNumberShift | (TUint16)error ); + } + CompleteChannelRequest( aRequest, error ); + break; + } + case EIADAsyncSendIndication: + { + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncSendIndication" ) ) ); + TUint32* tablePtr = reinterpret_cast( a1 ); + TAny* secondParam = reinterpret_cast(tablePtr[ KSecondParam ]); + ASSERT_RESET_ALWAYS( secondParam, EIADNullParameter | EIADFaultIdentifier26 << KFaultIdentifierShift ); + TInt msgLength( Kern::ThreadGetDesLength( iThread, secondParam ) ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncSendIndication TBR 0x%x %d" ), secondParam, msgLength ) ); + OstTraceExt2( TRACE_NORMAL, DUP11_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncSendIndication;secondParam=%x;msgLength=%d", (TUint)secondParam, msgLength ); + TInt error( KErrBadDescriptor ); + if( msgLength > 0 ) + { + // Previously there were Kern::Alloc (allocating from kernel memory a block where copy from user was made now only + // one copy from user to allocated block that is to be send. + TDes8& sendBlock = iExtensionApi->AllocateBlock( msgLength ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, secondParam, sendBlock, 0, KChunkShiftBy0 ), EIADDesReadFailed | EIADFaultIdentifier5 << KFaultIdentifierShift ); + TRACE_ASSERT_INFO( sendBlock.Length() == msgLength, (TUint8)iChannelNumber << KChannelNumberShift ); + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest EIADAsyncSendIndication 0x%x %d %d 0x%x" ), &sendBlock, sendBlock.Length(), msgLength, iChannelNumber ) ); + OstTraceExt5( TRACE_NORMAL, DUP13_DISAUSERCHANNEL_HANDLEASYNCREQUEST, "DISAUserChannel::HandleAsyncRequest EIADAsyncSendIndication;sendBlock=%x;sendBlock.Length()=%d;sendBlock.MaxLength()=%d;msgLength=%d;iChannelNumber=%hx", (TUint)&sendBlock, sendBlock.Length(), sendBlock.MaxLength(), msgLength, iChannelNumber ); + + error = iExtensionApi->SendIndication( sendBlock, iChannelNumber ); + } + else + { + error = msgLength; + TRACE_ASSERT_INFO( 0, (TUint8)iChannelNumber << KChannelNumberShift | (TUint16)error ); + } + CompleteChannelRequest( aRequest, error ); + break; + } + default: + { + ASSERT_RESET_ALWAYS( 0, EIADWrongRequest | EIADFaultIdentifier10 << KFaultIdentifierShift ); + break; + } + } + } + C_TRACE( ( _T( "DISAUserChannel::HandleAsyncRequest <-" ) ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_HANDLEASYNCREQUEST_EXIT, "" ) ) ); + ASSERT_CONTEXT_ALWAYS( NKern::EThread, 0 ); + TInt error( KErrNotSupported ); + switch( aRequest ) + { +#if (NCP_COMMON_SOS_VERSION_SUPPORT >= SOS_VERSION_95) + case EIADLoan: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADLoan" ) ) ); + OstTrace0( TRACE_NORMAL, DUY1_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADLoan" ); + TUint32* tablePtr = reinterpret_cast( a1 );; + iIADUserChannelNumberPtr = reinterpret_cast( tablePtr[ KFirstParam ] ); + ASSERT_RESET_ALWAYS( tablePtr[ KFirstParam ], EIADNullParameter | EIADFaultIdentifier27 << KFaultIdentifierShift ); + error = iExtensionApi->Loan( ~iChannelNumber, aRequest, this ); + TAny* tempUserChNmbrPtr( iIADUserChannelNumberPtr ); + // Check of KErrNone and KErrInUse (same object same id open) and in only those cases ~iCh = ~~iCh kernel already has. + TUint16 chNumber( ( KErrNone == error ? ~iChannelNumber : KNotInitializedChannel ) ); + iChannelNumber = chNumber; + ASSERT_RESET_ALWAYS( tempUserChNmbrPtr, 0 ); + // NOTE!!!!!!!! THIS MUST BE SET TO OWN DFC DUE TO DP, NOT URGENT CAUSE CALLER MOST LIKELY NOT SWAPPED. CHANGE REQUIRES LOAN TO BECOME ASYNC. + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadRawWrite( iThread, tempUserChNmbrPtr, &chNumber, sizeof(TUint16), iThread ), 0 ); + break; + } + case EIADReturnLoan: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADReturnLoan" ) ) ); + OstTrace0( TRACE_NORMAL, DUY2_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADReturnLoan" ); +// OLD WORKS, no cancellation of requests error = iExtensionApi->ReturnLoan( iChannelNumber, aRequest, this ); + // NEW + ResetQueues(); + if( KNotInitializedChannel != iChannelNumber ) + { + // Cancel any outstanding request. // remember in asynch close not to close it asynhronously + for( TInt i( 0 ); i < EIADAsyncLast; ++i ) + { + if( iReqQueue->GetReq( static_cast< TIADAsyncRequest >( i ) ) ) + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADReturnLoan req to cancel %d" ), i ) ); + OstTrace1( TRACE_NORMAL, DUY3_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADReturnLoan;reqToCancel=%d", i ); + DoCancel( KMaxTInt, i ); + } + } + // Must be called in extension context. + error = iExtensionApi->ReturnLoan( iChannelNumber, aRequest, this ); + } + //NEW + break; + } +#endif + case EIADClose: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADClose" ) ) ); + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADClose" ); + ResetQueues(); + if( KNotInitializedChannel != iChannelNumber ) + { + // Cancel any outstanding request. // remember in asynch close not to close it asynhronously + for( TInt i( 0 ); i < EIADAsyncLast; ++i ) + { + if( iReqQueue->GetReq( static_cast< TIADAsyncRequest >( i ) ) ) + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADClose req to cancel %d" ), i ) ); + OstTrace1( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADClose;reqToCancel=%d", i ); + DoCancel( KMaxTInt, i ); + } + } + // Must be called in extension context. + iExtensionApi->Close( iChannelNumber ); + error = KErrNone; + } + break; + } + case EIADSend: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADSend" ) ) ); + TUint32* tablePtr = reinterpret_cast( a1 ); + TAny* firstParam = reinterpret_cast(tablePtr[ KFirstParam ]); + ASSERT_RESET_ALWAYS( firstParam, EIADNullParameter | EIADFaultIdentifier27 << KFaultIdentifierShift ); + TInt msgLength( Kern::ThreadGetDesLength( iThread, firstParam ) ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADSend 0x%x %d" ), firstParam, msgLength ) ); + OstTraceExt2( TRACE_NORMAL, DUP2_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADSend;firstParam=%x;msgLength=%d", (TUint)firstParam, msgLength ); + + if( msgLength > 0 ) + { + // Previously there were Kern::Alloc (allocating from kernel memory a block where copy from user was made no only + // one copy from user to allocated block that is to be send. + TDes8& sendBlock = iExtensionApi->AllocateBlock( msgLength ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, firstParam, sendBlock, 0, KChunkShiftBy0 ), EIADDesReadFailed | EIADFaultIdentifier6 << KFaultIdentifierShift ); + TRACE_ASSERT_INFO( sendBlock.Length() == msgLength, (TUint8)iChannelNumber << KChannelNumberShift ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADSend 0x%x 0x%x" ), &sendBlock, iChannelNumber ) ); + OstTraceExt2( TRACE_NORMAL, DUP13_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADSend;sendBlock=%x;iChannelNumber=%hx", (TUint)&sendBlock, iChannelNumber ); + + error = iExtensionApi->SendMessage( sendBlock, iChannelNumber ); + } + else + { + error = ( msgLength == KErrNone ) ? KErrBadDescriptor : msgLength; + TRACE_ASSERT_INFO( 0, (TUint8)iChannelNumber << KChannelNumberShift | (TUint16)msgLength ); + } + break; + } + case EIADDataSend: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADDataSend" ) ) ); + TUint32* tablePtr = reinterpret_cast( a1 ); + TAny* firstParam = reinterpret_cast(tablePtr[ KFirstParam ]); + ASSERT_RESET_ALWAYS( firstParam, EIADNullParameter | EIADFaultIdentifier32 << KFaultIdentifierShift ); + TInt msgLength( Kern::ThreadGetDesLength( iThread, firstParam ) ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADDataSend 0x%x %d" ), firstParam, msgLength ) ); + OstTraceExt2( TRACE_NORMAL, DUP3_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADDataSend;firstParam=%x;msgLength=%d", (TUint)firstParam, msgLength ); + if( msgLength > 0 ) + { + // Previously there were Kern::Alloc (allocating from kernel memory a block where copy from user was made no only + // one copy from user to allocated block that is to be send. + + // Allocate a block for data. Allocation adds +11 to the msglength for pipe headers + TDes8& sendBlock = iExtensionApi->AllocateDataBlock( msgLength ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest max %d length %d" ), sendBlock.MaxLength(), sendBlock.Length() ) ); + // Use pre-allocated TPtr (no memory allocation from heap nor stack). + // Set it to point to +11 from sendblock and to be as long as data to be send + TInt tmpMaxLength( sendBlock.MaxLength() - KPipeDataHeader ); + TUint8* tmpPtr( const_cast( ( sendBlock.Ptr() + KPipeDataHeader ) ) ); + TPtr* test = static_cast( &sendBlock ); + test->Set( tmpPtr, 0, tmpMaxLength ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, firstParam, *test, 0, KChunkShiftBy0 ), EIADDesReadFailed | EIADFaultIdentifier7 << KFaultIdentifierShift ); + TInt tmpMaxLength2( sendBlock.MaxLength() + KPipeDataHeader ); + TInt tmpLength2( sendBlock.Length() + KPipeDataHeader ); + TUint8* tmpPtr2( const_cast( ( sendBlock.Ptr() - KPipeDataHeader ) ) ); + test->Set( tmpPtr2, tmpLength2, tmpMaxLength2 ); + TRACE_ASSERT_INFO( sendBlock.Length() > msgLength, (TUint8)iChannelNumber << KChannelNumberShift ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADDataSend 0x%x 0x%x" ), &sendBlock, iChannelNumber ) ); + OstTraceExt4( TRACE_NORMAL, DUP4_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADDataSend;sendBlock=%x;Length=%x;MaxLength=%x;iChannelNumber=%hx", (TUint)&sendBlock, sendBlock.Length(), sendBlock.MaxLength(), iChannelNumber ); + + error = iExtensionApi->SendMessage( sendBlock, iChannelNumber ); + } + else + { + error = ( msgLength == KErrNone ) ? KErrBadDescriptor : msgLength; + TRACE_ASSERT_INFO( 0, (TUint8)iChannelNumber << KChannelNumberShift | (TUint16)msgLength ); + } + break; + } + case EIADSubscribeIndications: + case EIADSubscribeIndications32Bit: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADSubscribeIndications | EIADSubscribeIndications32Bit" ) ) ); + TUint32* tablePtr = reinterpret_cast( a1 ); + TAny* firstParam = reinterpret_cast(tablePtr[ KFirstParam ]); + ASSERT_RESET_ALWAYS( firstParam, EIADNullParameter | EIADFaultIdentifier29 << KFaultIdentifierShift ); + TInt orderLength( Kern::ThreadGetDesLength( iThread, firstParam ) ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADSubscribeIndications | EIADSubscribeIndications32Bit 0x%x %d" ), firstParam, orderLength ) ); + OstTraceExt2( TRACE_NORMAL, DUP5_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADSubscribeIndications(8/32bit);firstParam=%x;orderLength=%d", (TUint)firstParam, orderLength ); + + if( orderLength > KErrNone ) + { + // Previously there were Kern::Alloc (allocating from kernel memory a block where copy from user was made no only + // one copy from user to allocated block that is to be send. + TDes8& sendBlock = iExtensionApi->AllocateBlock( ( orderLength ) ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, firstParam, sendBlock, 0, KChunkShiftBy0 ), EIADDesReadFailed | EIADFaultIdentifier8 << KFaultIdentifierShift ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADSubscribeIndications 0x%x 0x%x" ), &sendBlock, iChannelNumber ) ); + OstTraceExt2( TRACE_NORMAL, DUP7_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADSubscribeIndications(8/32bit);sendBlock=%x;iChannelNumber=%hx", (TUint)&sendBlock, iChannelNumber ); + TRACE_ASSERT_INFO( sendBlock.Length() == orderLength, (TUint8)iChannelNumber << KChannelNumberShift ); + // No return values check needed. Request completed with error value by multiplexer + TBool thirtyTwoBit( ( EIADSubscribeIndications32Bit == aRequest ) ? ETrue : EFalse ); + error = iExtensionApi->OrderIndication( sendBlock, iChannelNumber, thirtyTwoBit ); + iExtensionApi->DeAllocateBlock( sendBlock ); + } + else + { + error = orderLength; + TRACE_ASSERT_INFO( 0, (TUint8)iChannelNumber << KChannelNumberShift | (TUint16)error); + } + break; + } + case EIADSendIndication: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADSendIndication" ) ) ); + TUint32* tablePtr = reinterpret_cast( a1 ); + TAny* firstParam = reinterpret_cast(tablePtr[ KFirstParam ]); + ASSERT_RESET_ALWAYS( firstParam, EIADNullParameter | EIADFaultIdentifier30 << KFaultIdentifierShift ); + TInt msgLength( Kern::ThreadGetDesLength( iThread, firstParam ) ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADSendIndication TBR 0x%x %d" ), firstParam, msgLength ) ); + OstTraceExt2( TRACE_NORMAL, DUP6_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADSendIndication;firstParam=%x;msgLength=%d", (TUint)firstParam, msgLength ); + if( msgLength > KErrNone ) + { + // Previously there were Kern::Alloc (allocating from kernel memory a block where copy from user was made now only + // one copy from user to allocated block that is to be send. + TDes8& sendBlock = iExtensionApi->AllocateBlock( msgLength ); + ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, firstParam, sendBlock, 0, KChunkShiftBy0 ), EIADDesReadFailed | EIADFaultIdentifier9 << KFaultIdentifierShift ); + TRACE_ASSERT_INFO( sendBlock.Length() == msgLength, (TUint8)iChannelNumber << KChannelNumberShift ); + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADSendIndication 0x%x %d %d 0x%x" ), &sendBlock, sendBlock.Length(), msgLength, iChannelNumber ) ); + OstTraceExt4( TRACE_NORMAL, DUP8_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADSendIndication;sendBlock=%x;sendBlock.Length()=%d;msgLength=%d;iChannelNumber=%hx", (TUint)&sendBlock, sendBlock.Length(), msgLength, iChannelNumber ); + // No return values check needed. Request completed with error value by multiplexer + error = iExtensionApi->SendIndication( sendBlock, iChannelNumber ); + } + else + { + error = msgLength; + TRACE_ASSERT_INFO( 0, (TUint8)iChannelNumber << KChannelNumberShift | (TUint16)error ); + } + break; + } + case EIADGetMaxDataSize: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADGetMaxDataSize" ) ) ); + OstTrace0( TRACE_NORMAL, DUP9_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADGetMaxDataSize" ); + error = iExtensionApi->GetMaxDataSize(); + break; + } + case EIADGetConnectionStatus: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADGetConnectionStatus" ) ) ); + OstTrace0( TRACE_NORMAL, DUP10_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADGetConnectionStatus" ); + + error = iExtensionApi->GetConnectionStatus(); + break; + } + case EIADResetQueues: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADResetQueues" ) ) ); + OstTrace0( TRACE_NORMAL, DUP11_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADResetQueues" ); + + ResetQueues(); + error = KErrNone; + break; + } + case EIADGetFlowControlStatus: + { + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest EIADGetFlowControlStatus" ) ) ); + OstTrace0( TRACE_NORMAL, DUP12_DISAUSERCHANNEL_HANDLESYNCREQUEST, "DISAUserChannel::HandleSyncRequest EIADGetFlowControlStatus" ); + + error = iFlowCtrlStatus; + iLastNotifiedFlowCtrlStatus = error; + break; + } + default: + { + ASSERT_RESET_ALWAYS( 0, EIADWrongRequest | EIADFaultIdentifier11 << KFaultIdentifierShift ); + break; + } + } + C_TRACE( ( _T( "DISAUserChannel::HandleSyncRequest %d <-" ), error ) ); + + OstTrace1( TRACE_NORMAL, DISAUSERCHANNEL_HANDLESYNCREQUEST_EXIT, "DISAUserChannel::DoCancel;aRequest=%d;aMask=%d;iChannelNumber=%hx", aRequest, aMask, iChannelNumber ); + + C_TRACE( ( _T( "DISAUserChannel::DoCancel ->" ) ) ); + switch( aMask&aRequest ) + { + case EIADAsyncNotifyConnectionStatus: + { + C_TRACE( ( _T( "DISAUserChannel::DoCancel EIADAsyncNotifyConnectionStatus 0x%x" ), iIADConnectionStatusPtr ) ); + OstTrace1( TRACE_NORMAL, DISAUSERCHANNEL_DOCANCEL, "DISAUserChannel::DoCancel EIADAsyncNotifyConnectionStatus;iIADConnectionStatusPtr=%x", iIADConnectionStatusPtr ); + iIADConnectionStatusPtr = NULL; + break; + } + case EIADAsyncNotifyFlowControlStatus: + { + C_TRACE( ( _T( "DISAUserChannel::DoCancel EIADAsyncNotifyFlowControlStatus 0x%x" ), iIADFlowControlStatusPtr ) ); + OstTrace1( TRACE_NORMAL, DUP1_DISAUSERCHANNEL_DOCANCEL, "DISAUserChannel::DoCancel EIADAsyncNotifyFlowControlStatus;iIADFlowControlStatusPtr=%x", iIADFlowControlStatusPtr ); + + iIADFlowControlStatusPtr = NULL; + break; + } + case EIADAsyncReceive: + { + C_TRACE( ( _T( "DISAUserChannel::DoCancel EIADAsyncReceive 0x%x 0x%x" ), iReceiveBufPtr, iNeededBufLen ) ); + OstTraceExt2( TRACE_NORMAL, DUP2_DISAUSERCHANNEL_DOCANCEL, "DISAUserChannel::DoCancel EIADAsyncReceive;iReceiveBufPtr=%x;iNeededBufLen=%x", (TUint)iReceiveBufPtr, (TUint)iNeededBufLen ); + + iReceiveBufPtr = NULL; + iNeededBufLen = NULL; + break; + } + case EIADAsyncDataReceive: + { + C_TRACE( ( _T( "DISAUserChannel::DoCancel EIADAsyncDataReceive 0x%x 0x%x" ), iDataReceiveBufPtr, iNeededDataBufLen ) ); + OstTraceExt2( TRACE_NORMAL, DUP3_DISAUSERCHANNEL_DOCANCEL, "DISAUserChannel::DoCancel EIADAsyncDataReceive;iDataReceiveBufPtr=%x;iNeededDataBufLen=%x", (TUint)iDataReceiveBufPtr, (TUint)iNeededDataBufLen ); + + iDataReceiveBufPtr = NULL; + iNeededDataBufLen = NULL; + break; + } + case EIADAsyncOpen: + { + // Just complete with cancel + C_TRACE( ( _T( "DISAUserChannel::DoCancel EIADAsyncOpen" ) ) ); + OstTrace0( TRACE_NORMAL, DUP4_DISAUSERCHANNEL_DOCANCEL, "DISAUserChannel::DoCancel EIADAsyncOpen" ); + break; + } + case EIADAsyncSubscribeIndications: + case EIADAsyncSendIndication: + case EIADAsyncSubscribeIndications32Bit: + { + // Cause activation and cancelation request are run in the same thread. not actually possible to cancel request. + // Just complete with cancel. + C_TRACE( ( _T( "DISAUserChannel::DoCancel EIADAsyncSubscribeIndications | EIADAsyncSendIndication | EIADAsyncSubscribeIndications32bit" ) ) ); + OstTrace0( TRACE_NORMAL, DUP5_DISAUSERCHANNEL_DOCANCEL, "DISAUserChannel::DoCancel EIADAsyncSubscribeIndications | EIADAsyncSendIndication | EIADAsyncSubscribeIndications32Bit" ); + break; + } + case EIADAsyncSend: + { + // Just complete with cancel. + C_TRACE( ( _T( "DISAUserChannel::DoCancel EIADAsyncSend" ) ) ); + OstTrace0( TRACE_NORMAL, DUP6_DISAUSERCHANNEL_DOCANCEL, "DISAUserChannel::DoCancel EIADAsyncSend" ); + + break; + } + case EIADAsyncDataSend: + { + // Just complete with cancel. + C_TRACE( ( _T( "DISAUserChannel::DoCancel EIADAsyncSend" ) ) ); + OstTrace0( TRACE_NORMAL, DUP7_DISAUSERCHANNEL_DOCANCEL, "DISAUserChannel::DoCancel EIADAsyncDataSend" ); + + break; + } + default: + { + ASSERT_RESET_ALWAYS( 0, EIADWrongRequest | EIADFaultIdentifier12 << KFaultIdentifierShift ); + break; + } + } + CompleteChannelRequest( aMask&aRequest, KErrCancel ); + C_TRACE( ( _T( "DISAUserChannel::DoCancel <-" ) ) ); + + OstTrace0( TRACE_NORMAL, DISAUSERCHANNEL_DOCANCEL_EXIT, "