diff -r 000000000000 -r 164170e6151a wim/Scard/src/ScardNotifier.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wim/Scard/src/ScardNotifier.cpp Tue Jan 26 15:20:08 2010 +0200 @@ -0,0 +1,246 @@ +/* +* Copyright (c) 2003 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: Notification of events +* +*/ + + + +// INCLUDE FILES +#include "ScardServer.h" +#include "ScardNotifier.h" +#include "WimTrace.h" + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CScardNotifier::CScardNotifier +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CScardNotifier::CScardNotifier( + CScardNotifyRegistry* aRegistry, + RMessage2& aMessage, + TRequestStatus* aClientStatus, + const TReaderID& aReaderID ) + : CActive( EPriorityNormal ), + iRegistry( aRegistry ), + iMessage( aMessage ), + iClientStatus( aClientStatus ), + iReaderID( aReaderID ), + iMessageCompleted( EFalse ) + { + _WIMTRACE(_L("WIM|Scard|CScardNotifier::CScardNotifier|Begin")); + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CScardNotifier::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CScardNotifier::ConstructL() + { + _WIMTRACE(_L("WIM|Scard|CScardNotifier::ConstructL|Begin")); + //if the notifier is regular, no need to activate the ActiveObject. + //since the notifier can only be used once and will be deleted after + //the one-time notification is done. + if(!iClientStatus) + { + iEventStack = new( ELeave ) CArrayFixFlat( 1 ); + iStatus = KRequestPending; + SetActive(); + } + } + +// ----------------------------------------------------------------------------- +// CScardNotifier::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CScardNotifier* CScardNotifier::NewL( + CScardNotifyRegistry* aRegistry, + RMessage2& aMessage, + TRequestStatus* aClientStatus, + const TReaderID& aReaderID ) + { + _WIMTRACE(_L("WIM|Scard|CScardNotifier::NewL|Begin")); + CScardNotifier* self = new( ELeave ) CScardNotifier( + aRegistry, aMessage, aClientStatus, aReaderID ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + + +// Destructor +CScardNotifier::~CScardNotifier() + { + _WIMTRACE(_L("WIM|Scard|CScardNotifier::~CScardNotifier|Begin")); + if(!iClientStatus) + { + delete iEventStack; + Cancel(); + } + else + { + if ( !iMessageCompleted ) + { + iMessage.Complete( KErrNone ); + } + } + _WIMTRACE(_L("WIM|Scard|CScardNotifier::~CScardNotifier|End")); + } + +// ----------------------------------------------------------------------------- +// CScardNotifier::NotifyCardEvent +// Complete our own request, or if that's done already, store the event +// until it can be serviced... +// ----------------------------------------------------------------------------- +// +void CScardNotifier::NotifyCardEvent( + TScardServiceStatus aEvent, + TReaderID aReaderID ) + { + _WIMTRACE(_L("WIM|Scard|CScardNotifier::NotifyCardEvent|Begin")); + + //regular notifier + if( iClientStatus ) + { + _WIMTRACE(_L("WIM|Scard|CScardNotifier::NotifyCardEvent| a regular notifier")); + if(iMessageCompleted ) + { + return; + } + _WIMTRACE(_L("WIM|Scard|CScardNotifier::NotifyCardEvent|iMessage not used")); + _WIMTRACE(_L("WIM|Scard|CScardNotifier::NotifyCardEvent|Notify client")); + iMessage.Complete( aEvent ); + iMessageCompleted = ETrue; + _WIMTRACE(_L("WIM|Scard|CScardNotifier::NotifyCardEvent|Notify client DONE")); + return; + } + + _WIMTRACE(_L("WIM|Scard|CScardNotifier::NotifyCardEvent| Server notifier")); + // No need to store the event, just notify it + if ( iStatus == KRequestPending ) + { + TUint code( 0 ); + + // If this is the server notifier, + // it needs a different event encoding + if ( !iClientStatus ) + { + // The server needs to know both the event code and + // the reader ID, because it listens to all readers + + // Place the reader ID in the higher bytes... + code = aReaderID; + code <<= 4; + // ...and the event code in the low 4 bytes + code |= aEvent; + } + TRequestStatus* sp = &iStatus; + User::RequestComplete( sp, code ); + } + // Well, previous notify hasn't finished, so store the event + else + { + TCardEvent event; + event.iEvent = aEvent; + event.iReaderID = aReaderID; + TRAPD( err, iEventStack->AppendL( event ) ); + + if ( err != KErrNone ) // No reason to continue + { + User::Panic( _L( "Memory allocation error" ), err ); + } + } + } + +// ----------------------------------------------------------------------------- +// CScardNotifier::RunL +// Asynchronous request has finished +// ----------------------------------------------------------------------------- +// +void CScardNotifier::RunL() + { + _WIMTRACE2(_L("WIM|Scard|CScardNotifier::RunL|Begin, iClientStatus=%d"), iClientStatus); + // if this is a regular notifier, + // then some thing goes wrong. + // only server notifier should come to RunL(). + if ( iClientStatus ) + { + _WIMTRACE(_L("WIM|Scard|CScardNotifier::RunL|Only server notifer will come to RunL")); + } + // Otherwise this is the server notifier, so tell the server + else + { + _WIMTRACE(_L("WIM|Scard|CScardNotifier::RunL|server notifer")); + // the bit-shifting that was done when notifying is now reversed + TScardServiceStatus event = static_cast< TScardServiceStatus > + ( iStatus.Int() & 0x0f ); + TReaderID readerID = static_cast< TReaderID >( iStatus.Int() >> 4 ); + iRegistry->Server()->CardEvent( event, readerID ); + _WIMTRACE(_L("WIM|Scard|CScardNotifier::RunL|Server notification DONE")); + } + iStatus = KRequestPending; + SetActive(); + + // If there are any queued events, notify (first one of) them now + if ( iEventStack->Count() ) + { + _WIMTRACE(_L("WIM|Scard|CScardNotifier::RunL| Some queued event in server notifier")); + iRegistry->NotifyCardEvent( iEventStack->At( 0 ).iEvent, + iEventStack->At( 0 ).iReaderID ); + iEventStack->Delete( 0 ); + } + _WIMTRACE(_L("WIM|Scard|CScardNotifier::RunL|Exit")); + } + +// ----------------------------------------------------------------------------- +// CScardNotifier::DoCancel +// Active object cancelled +// ----------------------------------------------------------------------------- +// +void CScardNotifier::DoCancel() + { + _WIMTRACE3(_L("WIM|Scard|CScardNotifier::DoCancel|Begin, status=%d"), + iStatus.Int(), iClientStatus ); + iRegistry->Cancel( iStatus ); + _WIMTRACE(_L("WIM|Scard|CScardNotifier::DoCancel|Cancel called")); + + // If message not already completed do it here + if ( !iMessageCompleted && iClientStatus ) + { + iMessage.Complete( KErrCancel ); + _WIMTRACE(_L("WIM|Scard|CScardNotifier::DoCancel|Message completed")); + } + + _WIMTRACE(_L("WIM|Scard|CScardNotifier::DoCancel|End")); + } + +// ----------------------------------------------------------------------------- +// CScardNotifier::ReaderID +// Return readerID +// ----------------------------------------------------------------------------- +// +TReaderID CScardNotifier::ReaderId() + { + return iReaderID; + } +// End of File