wim/Scard/src/ScardAccessControl.cpp
changeset 0 164170e6151a
child 5 3b17fc5c9564
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 /*
       
     2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This object is the one responsible for trafficing between
       
    15 *                the Smart Card reader and the sessions.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include    "ScardServer.h"
       
    23 #include    "ScardReaderRegistry.h"
       
    24 #include    "ScardAccessControl.h"
       
    25 #include    "ScardAccessControlRegistry.h"
       
    26 #include    "ScardCommandTimer.h"
       
    27 #include    "ScardConnector.h"
       
    28 #include    <c32comm.h>         // Needed for RCommServ in WINS
       
    29 #include    "WimTrace.h"
       
    30 
       
    31 #ifdef _DEBUG // for logging
       
    32 #include    "ScardLogs.h"
       
    33 #include    <flogger.h> 
       
    34 #endif
       
    35 
       
    36 // ============================ MEMBER FUNCTIONS ===============================
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // TMessageHandle::TMessageHandle
       
    40 // C++ default constructor can NOT contain any code, that
       
    41 // might leave.
       
    42 // -----------------------------------------------------------------------------
       
    43 //
       
    44 TMessageHandle::TMessageHandle(
       
    45     const RMessage2& aMessage,
       
    46     const TInt aSessionID,
       
    47     const TReaderID aReaderID,
       
    48     const TInt8 aChannel,
       
    49     const TInt8 aAddition)
       
    50     : iMessage( aMessage ),
       
    51       iSessionID( aSessionID ),
       
    52       iReaderID( aReaderID ), 
       
    53       iCancelled( EFalse ),
       
    54       iChannel( aChannel ),
       
    55       iTimer( NULL ), 
       
    56       iAdditionalParameter( aAddition )
       
    57     {
       
    58     }
       
    59 
       
    60 // -----------------------------------------------------------------------------
       
    61 // TMessageHandle::TMessageHandle
       
    62 // C++ default constructor can NOT contain any code, that
       
    63 // might leave.
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 TMessageHandle::TMessageHandle()
       
    67     : iMessage(), 
       
    68       iSessionID( ENoSession ),
       
    69       iReaderID( 0 ),
       
    70       iCancelled( EFalse ), 
       
    71       iChannel( 0 ),
       
    72       iTimer( NULL ),
       
    73       iAdditionalParameter( 0 )
       
    74     {
       
    75     }
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // CScardAccessControl::CScardAccessControl
       
    79 // C++ default constructor can NOT contain any code, that
       
    80 // might leave.
       
    81 // -----------------------------------------------------------------------------
       
    82 //
       
    83 CScardAccessControl::CScardAccessControl(
       
    84     const TReaderID aReaderID, 
       
    85     CScardAccessControlRegistry* aControlRegistry )
       
    86     : CActive( EPriorityNormal ), 
       
    87       iSessionRegistry( NULL ),
       
    88       iReaderActive( EFalse ),
       
    89       iIsCreated( EFalse ),
       
    90       iIsOpen( EFalse ),
       
    91       iNextSessionID( 1 ),
       
    92       iReader( NULL ),
       
    93       iReaderID( aReaderID ),
       
    94       iControlRegistry( aControlRegistry ),
       
    95       iManager( NULL ),
       
    96       iLifeMode( ECanBeDeleted )
       
    97     {
       
    98     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::CScardAccessControl|Begin"));
       
    99     CActiveScheduler::Add( this );
       
   100     }
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CScardAccessControl::ConstructL
       
   104 // Symbian 2nd phase constructor can leave.
       
   105 // -----------------------------------------------------------------------------
       
   106 //
       
   107 void CScardAccessControl::ConstructL()
       
   108     {
       
   109     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::ConstructL|Begin"));
       
   110     iSessionRegistry = new( ELeave ) CArrayFixFlat<TReaderSession>( 1 );
       
   111     iManager = CScardChannelManager::NewL();
       
   112     }
       
   113 
       
   114 // -----------------------------------------------------------------------------
       
   115 // CScardAccessControl::NewL
       
   116 // Two-phased constructor.
       
   117 // -----------------------------------------------------------------------------
       
   118 //
       
   119 CScardAccessControl* CScardAccessControl::NewL(
       
   120     const TReaderID aReaderID, 
       
   121     CScardAccessControlRegistry* aControl )
       
   122     {
       
   123     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::NewL|Begin"));
       
   124     CScardAccessControl* self = new( ELeave ) CScardAccessControl( aReaderID, 
       
   125         aControl );
       
   126     
       
   127     CleanupStack::PushL( self );
       
   128     self->ConstructL();
       
   129     CleanupStack::Pop( self );
       
   130 
       
   131 #ifdef _DEBUG    
       
   132     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   133         EFileLoggingModeAppend, 
       
   134         _L( "Access controller created.\n" ) );
       
   135 #endif
       
   136     return self;
       
   137     }
       
   138 
       
   139     
       
   140 // Destructor
       
   141 CScardAccessControl::~CScardAccessControl()
       
   142     {
       
   143     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::~CScardAccessControl|Begin"));
       
   144     Cancel();
       
   145 
       
   146     if ( iIsCreated )
       
   147         {
       
   148         DetachSessionFromReader( EAccessMasterID );
       
   149         }
       
   150     if ( iControlRegistry )
       
   151         {
       
   152         iControlRegistry->ControllerRetired( this );
       
   153         }
       
   154     delete iSessionRegistry;
       
   155     delete iManager;
       
   156 #ifdef _DEBUG    
       
   157     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   158         EFileLoggingModeAppend, 
       
   159         _L( "Access controller destroyed.\n" ) );
       
   160 #endif
       
   161     }
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CScardAccessControl::InitiateCommunication
       
   165 // Set the reader as active. Prevents polling and other sessions 
       
   166 // from using the reader. Returns the request status of this object.
       
   167 // -----------------------------------------------------------------------------
       
   168 //
       
   169 TRequestStatus& CScardAccessControl::InitiateCommunication(
       
   170     const TInt aSessionID,
       
   171     const RMessage2& aMessage, 
       
   172     const TInt32 aTimeOut,
       
   173     const TInt8 aChannel,
       
   174     const TUint8 aAdditionalParameter )
       
   175     {
       
   176     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::InitiateCommunication|Begin"));
       
   177 #ifdef _DEBUG    
       
   178     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   179         EFileLoggingModeAppend, 
       
   180         _L( "CScardAccessControl::InitiateCommunication session: %d, channel:\
       
   181         %d, reader: %d\n" ), aSessionID, aChannel, iReaderID );
       
   182 #endif
       
   183     iReaderActive = ETrue;
       
   184 
       
   185     TMessageHandle handle( aMessage, aSessionID, iReaderID, aChannel, 
       
   186         aAdditionalParameter );
       
   187     if ( aTimeOut )
       
   188         {
       
   189 #ifdef _DEBUG    
       
   190         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   191             EFileLoggingModeAppend, 
       
   192             _L( "CScardAccessControl::InitiateCommunication create command\
       
   193             timer\n" ) );
       
   194 #endif
       
   195         TRAPD( err, 
       
   196             handle.iTimer = CScardCommandTimer::NewL( aTimeOut, this ) );
       
   197         if ( err )
       
   198             {
       
   199             return iStatus;
       
   200             }
       
   201         handle.iTimer->StartTiming();
       
   202         }
       
   203 
       
   204     TRAPD( err, iManager->PushMessageToTopL( handle ) );
       
   205     if ( !err )
       
   206         {
       
   207         SetActive();
       
   208         }
       
   209     iStatus = err;
       
   210     _WIMTRACE2(_L("WIM|Scard|CScardAccessControl::InitiateCommunication|End|iStatus=%d"), err);
       
   211     return iStatus;
       
   212     }
       
   213 
       
   214 // -----------------------------------------------------------------------------
       
   215 // CScardAccessControl::ReaderIsReady
       
   216 // Ask if the reader is available to use for aSessionID.
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 TBool CScardAccessControl::ReaderIsReady(
       
   220     const TInt aSessionID, 
       
   221     const TInt8 aChannel ) const 
       
   222     {
       
   223     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::ReaderIsReady|Begin"));
       
   224     TInt res( 0 );
       
   225 
       
   226     TRAPD( err, res = iManager->ChannelReservedL( aChannel ) );
       
   227     if ( err )
       
   228         {
       
   229         return EFalse;
       
   230         }
       
   231     if ( res )
       
   232         {
       
   233         if ( res != aSessionID && aSessionID != EAccessMasterID )
       
   234             {
       
   235 #ifdef _DEBUG    
       
   236             RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   237             EFileLoggingModeAppend, 
       
   238             _L( "CScardAccessControl::ReaderIsReady: Channel reserved by\
       
   239             another session.\n" ) );
       
   240 #endif
       
   241             return EFalse;
       
   242             }
       
   243         }
       
   244     
       
   245     if ( iReaderActive ) 
       
   246         {
       
   247 #ifdef _DEBUG    
       
   248         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   249             EFileLoggingModeAppend, 
       
   250             _L( "CScardAccessControl::ReaderIsReady: Reader active.\n" ) );
       
   251 #endif
       
   252         return EFalse;
       
   253         }
       
   254     else
       
   255         {
       
   256         return ETrue;
       
   257         }
       
   258     }
       
   259 
       
   260 // -----------------------------------------------------------------------------
       
   261 // CScardAccessControl::FreeChannelL
       
   262 // Free current reservation (if this session has a reservation)
       
   263 // If there are messages in the stack, service them.
       
   264 // -----------------------------------------------------------------------------
       
   265 //
       
   266 void CScardAccessControl::FreeChannelL(
       
   267     const TInt aSessionID, 
       
   268     const TInt8 aChannel )
       
   269     {
       
   270     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::FreeChannelL|Begin"));
       
   271     if ( aChannel == KAllChannels )
       
   272         {
       
   273         iManager->FreeChannels( aSessionID );
       
   274         }
       
   275     else
       
   276         {
       
   277         iManager->FreeChannelL( aChannel, aSessionID );
       
   278         }
       
   279 
       
   280     if ( !iReaderActive )
       
   281         {
       
   282         HandleNextMessageL( iManager->NextMessageFromFree( aChannel ) );
       
   283         }
       
   284     }
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CScardAccessControl::RunL
       
   288 // Handle completed reader messages by finding the caller, and calling 
       
   289 // the complete function. Also take the next message from the stack (if 
       
   290 // present) and start handling it.
       
   291 // -----------------------------------------------------------------------------
       
   292 //
       
   293 void CScardAccessControl::RunL()
       
   294     {
       
   295     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::RunL|Begin"));
       
   296 #ifdef _DEBUG        
       
   297     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   298         EFileLoggingModeAppend, 
       
   299         _L( "CScardAccessControl::RunL\n" ) );
       
   300 #endif
       
   301     iLifeMode = ECanNotDelete;
       
   302 
       
   303     //  reader has finished, mark it as inactive
       
   304     iReaderActive = EFalse;
       
   305     
       
   306     //  Get the message that was serviced, and the session that made the 
       
   307     //  request
       
   308     TMessageHandle msgHandle = iManager->MessageFromTop();
       
   309 
       
   310     //  Controller needs to know if a connection has been successful
       
   311     if ( msgHandle.iAdditionalParameter == KOpenReader ) 
       
   312         {
       
   313         // If connection was succesful, ConnectionDone() is called from
       
   314         // notifier. Otherwise, call it from here.
       
   315         if ( iStatus == KErrNone )
       
   316             {
       
   317             iIsOpen = ETrue;
       
   318             }
       
   319         else 
       
   320             {
       
   321             iControlRegistry->Server()->ConnectionRegistry()->
       
   322                 Connection( 0 ).iConnector->ConnectionDone( 
       
   323                 msgHandle.iReaderID, iStatus.Int() );
       
   324             }
       
   325         }
       
   326 
       
   327     //  Handle result in appropriate session
       
   328     //  In case the operation was cancelled, continue from the next operation
       
   329     //  w/o completing the last one.
       
   330     //  In case of connecting to reader, ConnectionDone() takes care of 
       
   331     //  completing the message. 
       
   332     if ( !msgHandle.iCancelled &&
       
   333         msgHandle.iAdditionalParameter != KOpenReader )
       
   334         {
       
   335         CScardSession* session = SessionBase( msgHandle.iSessionID );
       
   336         if ( !session )
       
   337             {
       
   338             User::Panic( _L( "Message stack fault" ), 
       
   339                 KScServerPanicInternalError );
       
   340             }
       
   341 #ifdef _DEBUG    
       
   342         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   343             EFileLoggingModeAppend, 
       
   344             _L( "CScardAccessControl::RunL: Message %x completed with status\
       
   345             %d.\n" ), msgHandle.iAdditionalParameter, iStatus.Int() );
       
   346 #endif
       
   347         session->AsynchronousServiceComplete( msgHandle, iStatus.Int() );
       
   348         }
       
   349 
       
   350     //  The session may have indicated that it's about time for this 
       
   351     //  object to destroy itself
       
   352     if ( iLifeMode == EDestroyASAP )
       
   353         {
       
   354         delete this;
       
   355         return;
       
   356         }
       
   357 
       
   358     iLifeMode = ECanBeDeleted;
       
   359 
       
   360     //  Check for queued messages. 
       
   361     HandleNextMessageL( iManager->NextMessageL() );
       
   362     }
       
   363 
       
   364 // -----------------------------------------------------------------------------
       
   365 // CScardAccessControl::DoCancel
       
   366 // Instruct the reader to cancel
       
   367 // -----------------------------------------------------------------------------
       
   368 //
       
   369 void CScardAccessControl::DoCancel()
       
   370     {
       
   371     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::DoCancel|Begin"));
       
   372     if ( iReader )
       
   373         {
       
   374 #ifdef _DEBUG    
       
   375         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   376             EFileLoggingModeAppend, 
       
   377             _L( "CScardAccessControl::DoCancel: Canceling transmissions.\n" ) );
       
   378 #endif
       
   379         TRAPD( err, CancelTransmissionsL( EAccessMasterID ) );
       
   380         
       
   381         if ( err != KErrNone )
       
   382             {
       
   383             // Do nothing
       
   384             }
       
   385         }
       
   386     }
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 // CScardAccessControl::QueueExecution
       
   390 // Queue the execution of a command until it can be serviced
       
   391 // -----------------------------------------------------------------------------
       
   392 //
       
   393 void CScardAccessControl::QueueExecution(
       
   394     const RMessage2& aMessage, 
       
   395     const TInt aSessionID,
       
   396     const TInt32 aTimeOut, 
       
   397     const TInt8 aChannel, 
       
   398     const TInt8 aParameter )
       
   399     {
       
   400     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::QueueExecution|Begin"));
       
   401     TMessageHandle tmp( aMessage, aSessionID, iReaderID, aChannel, aParameter );
       
   402     TInt err;
       
   403     if ( aTimeOut )
       
   404         {
       
   405         TRAP( err, tmp.iTimer = CScardCommandTimer::NewL( aTimeOut, this ) );
       
   406         if ( err )
       
   407             {
       
   408             tmp.iMessage.Complete( err );
       
   409             }
       
   410         tmp.iTimer->StartTiming();
       
   411         }
       
   412 
       
   413     TRAP( err, iManager->PushMessageToBottomL( tmp ) );
       
   414     if ( err )
       
   415         {
       
   416         tmp.iMessage.Complete( err );
       
   417         }
       
   418     }
       
   419 
       
   420 // -----------------------------------------------------------------------------
       
   421 // CScardAccessControl::QueueChannelOperation
       
   422 // Queue channel operation
       
   423 // -----------------------------------------------------------------------------
       
   424 //
       
   425 void CScardAccessControl::QueueChannelOperation(
       
   426     const RMessage2& aMessage, 
       
   427     const TInt aSessionID, 
       
   428     const TInt32 aTimeOut, 
       
   429     const TInt8 aChannel )
       
   430     {
       
   431     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::QueueChannelOperation|Begin"));
       
   432     TMessageHandle tmp( aMessage, aSessionID, iReaderID, aChannel,
       
   433         KReservation );
       
   434     if ( aTimeOut )
       
   435         {
       
   436         TRAPD( err, tmp.iTimer = CScardCommandTimer::NewL( aTimeOut, this ) );
       
   437         if ( err )
       
   438             {
       
   439             tmp.iMessage.Complete( err );
       
   440             }
       
   441         tmp.iTimer->StartTiming();
       
   442         }
       
   443 
       
   444     TRAPD( err, iManager->PushMessageToBottomL( tmp ) );
       
   445     if ( err )
       
   446         {
       
   447         tmp.iMessage.Complete( err );
       
   448         }
       
   449     }
       
   450 
       
   451 // -----------------------------------------------------------------------------
       
   452 // CScardAccessControl::IsAttached
       
   453 // Is this session attached to the reader yet?
       
   454 // -----------------------------------------------------------------------------
       
   455 //
       
   456 TBool CScardAccessControl::IsAttached( CScardSession* aSession ) const
       
   457     {
       
   458     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::IsAttached|Begin"));
       
   459     TInt sessionCount = iSessionRegistry->Count();
       
   460     for ( TInt i( 0 ); i < sessionCount; i++ )
       
   461         {
       
   462         if ( (*iSessionRegistry)[i].SessionBase == aSession )
       
   463             {
       
   464             return ETrue;
       
   465             }
       
   466         }
       
   467     return EFalse;
       
   468     }
       
   469 
       
   470 // -----------------------------------------------------------------------------
       
   471 // CScardAccessControl::SessionBase
       
   472 // Returns CScardSession* belonging to this session id
       
   473 // -----------------------------------------------------------------------------
       
   474 //
       
   475 CScardSession* CScardAccessControl::SessionBase( const TInt aSessionID )
       
   476     {
       
   477     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::SessionBase|Begin"));
       
   478     TInt sessionCount = iSessionRegistry->Count();
       
   479     for ( TInt i( 0 ); i < sessionCount; i++ )
       
   480         {
       
   481         if ( (*iSessionRegistry)[i].SessionID == aSessionID )
       
   482             {
       
   483             return (*iSessionRegistry)[i].SessionBase;
       
   484             }
       
   485         }
       
   486     return NULL;
       
   487     }
       
   488 
       
   489 // -----------------------------------------------------------------------------
       
   490 // CScardAccessControl::CardEvent
       
   491 // Handle card event
       
   492 // -----------------------------------------------------------------------------
       
   493 //
       
   494 void CScardAccessControl::CardEvent(
       
   495     const TScardServiceStatus aEvent, 
       
   496     const TScardATR& aATR )
       
   497     {
       
   498     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::CardEvent|Begin"));
       
   499 
       
   500     if ( aATR.Length() )
       
   501         {
       
   502         iATR = aATR;
       
   503         }
       
   504 
       
   505     if ( aEvent == EScardRemoved )
       
   506         {
       
   507         iManager->CardRemoved();
       
   508         }
       
   509 
       
   510     TInt sessionCount = iSessionRegistry->Count();
       
   511 
       
   512     for ( TInt index( 0 ); index < sessionCount ; index++ )
       
   513         {
       
   514         iSessionRegistry->At( index ).SessionBase->CardEvent( aEvent, aATR, 
       
   515             iReaderID );
       
   516         }
       
   517     }
       
   518 
       
   519 // -----------------------------------------------------------------------------
       
   520 // CScardAccessControl::CancelTransmissionsL
       
   521 // Cancel Transmissions
       
   522 // -----------------------------------------------------------------------------
       
   523 //
       
   524 void CScardAccessControl::CancelTransmissionsL( const TInt aSessionID )
       
   525     {
       
   526     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::CancelTransmissions|Begin"));
       
   527 #ifdef _DEBUG    
       
   528     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   529         EFileLoggingModeAppend, 
       
   530         _L( "CScardAccessControl::CancelTransmissions: Purge messages from \
       
   531         stack.\n" ) );
       
   532 #endif
       
   533     //  First purge the messages from the stack
       
   534     iManager->CancelAll( aSessionID );
       
   535 
       
   536     //  If the message currently served is for the calling session, cancel it 
       
   537     //  from the reader also and put it back
       
   538     TMessageHandle tmp = iManager->MessageFromTop();
       
   539     if ( tmp.iSessionID == aSessionID || aSessionID == EAccessMasterID )
       
   540         {
       
   541 #ifdef _DEBUG    
       
   542         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   543             EFileLoggingModeAppend, 
       
   544             _L( "CScardAccessControl::CancelTransmissions: Cancel message from\
       
   545             reader.\n" ) );
       
   546 #endif
       
   547      
       
   548         iReader->CancelTransmit();
       
   549         
       
   550         if ( aSessionID == EAccessMasterID )
       
   551             {
       
   552             // reader not active anymore
       
   553             iReaderActive = EFalse;
       
   554             }    
       
   555         }
       
   556 
       
   557     if ( tmp.iSessionID != ENoSession && aSessionID != EAccessMasterID )
       
   558         {
       
   559         iManager->PushMessageToTopL( tmp );
       
   560         }
       
   561 
       
   562     //  Finish by clearing any reservations the cancelling session has done
       
   563 #ifdef _DEBUG    
       
   564     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   565         EFileLoggingModeAppend, 
       
   566         _L( "CScardAccessControl::CancelTransmissions: Free reserved\
       
   567         channels.\n" ) );
       
   568 #endif
       
   569     iManager->FreeChannels( aSessionID );
       
   570     }
       
   571 
       
   572 // -----------------------------------------------------------------------------
       
   573 // CScardAccessControl::DetachSessionFromReader
       
   574 // Detach session from reader
       
   575 // -----------------------------------------------------------------------------
       
   576 //
       
   577 void CScardAccessControl::DetachSessionFromReader( const TInt aSessionID )
       
   578     {
       
   579     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::DetachSessionFromReader|Begin"));
       
   580     if ( aSessionID == EAccessMasterID )
       
   581         {
       
   582 #ifdef _DEBUG    
       
   583         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   584             EFileLoggingModeAppend, 
       
   585             _L( "CScardAccessControl::DetachSessionFromReader: Detach all\
       
   586             sessions...\n" ) );
       
   587 #endif
       
   588 
       
   589         //  detach all sessions and delete all their messages
       
   590         DequeueOperations( EAccessMasterID );
       
   591         while ( iSessionRegistry->Count() )
       
   592             {
       
   593             iSessionRegistry->Delete( 0 );
       
   594             }
       
   595 
       
   596         //  all sessions have been detached, so kill the reader (if it's around)
       
   597         if ( iReader )
       
   598             {
       
   599             iReader->Close();
       
   600             }
       
   601         iControlRegistry->Server()->FactoryRegistry()->CloseReader(
       
   602                 iReaderID );
       
   603         iReader = NULL;
       
   604         iIsOpen = EFalse;
       
   605         iIsCreated = EFalse;
       
   606         }
       
   607     
       
   608     else
       
   609         {
       
   610 #ifdef _DEBUG    
       
   611         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   612             EFileLoggingModeAppend, 
       
   613             _L( "CScardAccessControl::DetachSessionFromReader: Detach session\
       
   614             %d...\n" ), aSessionID );
       
   615 #endif
       
   616         TInt i( 0 );
       
   617         if ( !IsAttached( SessionBase( aSessionID ) ) ) 
       
   618             {
       
   619 #ifdef _DEBUG    
       
   620             RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   621                 EFileLoggingModeAppend, 
       
   622                 _L( "CScardAccessControl::DetachSessionFromReader: Session not\
       
   623                 attached!!!\n" ), aSessionID );
       
   624 #endif
       
   625             return;
       
   626             }
       
   627         
       
   628         //  locate the session to be detached
       
   629         for ( ; (*iSessionRegistry)[i].SessionID != aSessionID; i++ )
       
   630             {;}
       
   631         
       
   632         iSessionRegistry->Delete( i );
       
   633 
       
   634         //  pop out all messages queued to it
       
   635         DequeueOperations( aSessionID );
       
   636 
       
   637         //  Free any possible transactions with the smart card
       
   638         TRAPD( error, FreeChannelL( aSessionID, KAllChannels ) );
       
   639 
       
   640         if ( error != KErrNone )
       
   641             {
       
   642             // Do nothing
       
   643             }
       
   644         }
       
   645     }
       
   646 
       
   647 // -----------------------------------------------------------------------------
       
   648 // CScardAccessControl::DequeueOperations
       
   649 // Cancel all pending messages
       
   650 // -----------------------------------------------------------------------------
       
   651 //
       
   652 void CScardAccessControl::DequeueOperations( const TInt aSessionID )
       
   653     {
       
   654     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::DequeueOperations|Begin"));
       
   655     iManager->CancelAll( aSessionID );
       
   656     }
       
   657 
       
   658 // -----------------------------------------------------------------------------
       
   659 // CScardAccessControl::InitialiseReader
       
   660 // Initialise reader handler
       
   661 // -----------------------------------------------------------------------------
       
   662 //
       
   663 TBool CScardAccessControl::InitialiseReader(
       
   664     const TInt aSessionID, 
       
   665     const RMessage2& aMessage )
       
   666     {
       
   667     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::InitialiseReader|Begin"));
       
   668     if ( iIsOpen )
       
   669         {
       
   670 #ifdef _DEBUG    
       
   671         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   672             EFileLoggingModeAppend, 
       
   673             _L( "CScardAccessControl::InitialiseReader: Reader already\
       
   674             open.\n" ) );
       
   675 #endif
       
   676         return ETrue;
       
   677         }
       
   678 
       
   679     if ( ReaderIsReady( EAccessMasterID, 0 ) )
       
   680         {
       
   681         InitiateCommunication( aSessionID, aMessage, static_cast< TInt32>( 0 ),
       
   682             0, KOpenReader );
       
   683 #if defined (__WINS__)
       
   684         RCommServ commServer;
       
   685         TInt error = commServer.Connect();
       
   686         if ( error == KErrNone)
       
   687             {
       
   688             commServer.Close();         	
       
   689             }
       
   690 #endif
       
   691 #ifdef _DEBUG    
       
   692         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   693             EFileLoggingModeAppend, 
       
   694             _L( "CScardAccessControl::InitialiseReader: Opening Reader\n" ) );
       
   695 #endif
       
   696         iReader->Open( iStatus );
       
   697         }
       
   698 #ifdef _DEBUG    
       
   699     else 
       
   700         {
       
   701         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   702           EFileLoggingModeAppend, 
       
   703           _L( "CScardAccessControl::InitialiseReader: Reader not ready!.\n" ) );
       
   704         }
       
   705 #endif
       
   706     return EFalse;
       
   707     }
       
   708 
       
   709 // -----------------------------------------------------------------------------
       
   710 // CScardAccessControl::AttachSessionToReaderL
       
   711 // Attach session to reader
       
   712 // -----------------------------------------------------------------------------
       
   713 //
       
   714 MScardReader* CScardAccessControl::AttachSessionToReaderL(
       
   715     CScardSession* aSession, 
       
   716     TInt &aSessionID )
       
   717     {
       
   718     _WIMTRACE(_L("WIM|Scard|CScardAccessControl::AttachSessionToReaderL|Begin"));
       
   719     TReaderSession newSession;
       
   720     newSession.SessionID = iNextSessionID;
       
   721     newSession.SessionBase = aSession;
       
   722 
       
   723     TInt readerCreationError( 0 );  
       
   724 
       
   725     //  If no other session has connected yet or the reader launcher has been
       
   726     //  unable to create the reader object, go here...
       
   727     if ( !iIsCreated )
       
   728         {
       
   729 #ifdef _DEBUG    
       
   730         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   731             EFileLoggingModeAppend, 
       
   732             _L( "CScardAccessControl::AttachSessionToReader: reader not\
       
   733             created!\n" ) );
       
   734 #endif
       
   735         //  ... and ask the launcher to create the reader object
       
   736         CScardReaderRegistry* reg = 
       
   737             iControlRegistry->Server()->FactoryRegistry();
       
   738         TRAP( readerCreationError, iReader = reg->LoadReaderL( iReaderID ) );
       
   739         }
       
   740     
       
   741 #ifdef _DEBUG        
       
   742     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   743         EFileLoggingModeAppend, 
       
   744         _L( "CScardAccessControl::AttachSessionToReader: session ID %d\n" ),
       
   745         newSession.SessionID );
       
   746 #endif
       
   747 
       
   748     iSessionRegistry->AppendL( newSession );
       
   749     
       
   750     // Place session ID and increment the next ID
       
   751     aSessionID = iNextSessionID++;
       
   752 
       
   753     //  All sessions are immediately on channel 0
       
   754     iManager->AddSessionToChannelL( KChannel0, aSessionID );
       
   755 
       
   756     if ( !readerCreationError && iReader )
       
   757         {
       
   758         iIsCreated = ETrue;
       
   759         return iReader;
       
   760         }
       
   761     else
       
   762         {
       
   763 #ifdef _DEBUG    
       
   764         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   765             EFileLoggingModeAppend, 
       
   766             _L( "CScardAccessControl::AttachSessionToReader: reader creation\
       
   767             failed!!!\n" ) );
       
   768 #endif
       
   769         iIsCreated = EFalse;
       
   770         User::Leave( readerCreationError );
       
   771         return NULL;
       
   772         }
       
   773     }
       
   774 
       
   775 //  End of File