--- /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<TCardEvent>( 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