wim/Scard/src/ScardConnector.cpp
changeset 0 164170e6151a
child 42 82671cd8994b
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:  A connection to a smart card
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    "ScardConnector.h"
       
    22 #include    "ScardConnectionRegistry.h"
       
    23 #include    "ScardAccessControl.h"
       
    24 #include    "ScardAccessControlRegistry.h"
       
    25 #include    "ScardConnectionTimer.h"
       
    26 #include    "ScardServer.h"
       
    27 #include    "ScardServerBase.h"
       
    28 #include    "WimTrace.h"
       
    29 
       
    30 #ifdef _DEBUG // for logging
       
    31 #include    "ScardLogs.h"
       
    32 #include    <flogger.h> 
       
    33 #endif
       
    34 
       
    35 // ============================ MEMBER FUNCTIONS ===============================
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // TConnectionParameter::TConnectionParameter
       
    39 // C++ default constructor can NOT contain any code, that
       
    40 // might leave.
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 TConnectionParameter::TConnectionParameter()
       
    44     : iReaderName( NULL ), 
       
    45       iExcluded( NULL ), 
       
    46       iATRBytes( NULL ),
       
    47       iAIDBytes( NULL ),
       
    48       iNewCardOnly( EFalse ), 
       
    49       iNewReaderOnly( EFalse )
       
    50     {
       
    51     _WIMTRACE(_L("WIM|Scard|TConnectionParameter::TConnectionParameter|Begin"));
       
    52     }
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // TConnection::TConnection
       
    56 // C++ default constructor can NOT contain any code, that
       
    57 // might leave.
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 TConnection::TConnection()
       
    61     : iCtrl( NULL ), 
       
    62       iReader( NULL ), 
       
    63       iReaderID( 0 ), 
       
    64       iSessionID( ENoSession )
       
    65     {
       
    66     }
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 // Compare two connections
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 TBool operator==(
       
    73     const TConnection& aConnection1, 
       
    74     const TConnection& aConnection2 )
       
    75     {
       
    76     if ( aConnection1.iReader == aConnection2.iReader && 
       
    77         aConnection1.iCtrl == aConnection2.iCtrl &&
       
    78         aConnection1.iSessionID == aConnection2.iSessionID &&
       
    79         aConnection1.iReaderID == aConnection2.iReaderID )
       
    80         {
       
    81         return ETrue;
       
    82         }
       
    83     return EFalse;
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CScardConnector::CScardConnector
       
    88 // C++ default constructor can NOT contain any code, that
       
    89 // might leave.
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 CScardConnector::CScardConnector(
       
    93     CScardConnectionRegistry* aConnRegistry, 
       
    94     RThread& /*aClient*/ )
       
    95     : CScardSession(),
       
    96       iConnectionRegistry( aConnRegistry ),
       
    97       iState( EActive )
       
    98     {
       
    99     _WIMTRACE(_L("WIM|Scard|CScardConnector::CScardConnector|Begin"));
       
   100     }
       
   101 
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // CScardConnector::ConstructL
       
   105 // Symbian 2nd phase constructor can leave.
       
   106 // -----------------------------------------------------------------------------
       
   107 //
       
   108 void CScardConnector::ConstructL( const RMessage2& aMessage )
       
   109     {
       
   110     _WIMTRACE(_L("WIM|Scard|CScardConnector::ConstructL|Begin"));
       
   111     iConnections = new( ELeave ) CArrayFixFlat<TConnection>( 1 );
       
   112     iStack = CScardEventStack::NewL( this );
       
   113     iClientMessage = new( ELeave ) RMessage2( aMessage ); 
       
   114     iState = EActive;
       
   115     }
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CScardConnector::NewL
       
   119 // Two-phased constructor.
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 CScardConnector* CScardConnector::NewL(
       
   123     CScardConnectionRegistry* aConnRegistry, 
       
   124     RThread& aClient, 
       
   125     const RMessage2& aMessage )
       
   126     {
       
   127     _WIMTRACE(_L("WIM|Scard|CScardConnector::NewL|Begin"));
       
   128     CScardConnector* self = new( ELeave ) CScardConnector( aConnRegistry, 
       
   129         aClient );
       
   130     
       
   131     CleanupStack::PushL( self );
       
   132     self->ConstructL( aMessage );
       
   133     CleanupStack::Pop( self );
       
   134 
       
   135     return self;
       
   136     }
       
   137 
       
   138     
       
   139 // Destructor
       
   140 CScardConnector::~CScardConnector()
       
   141     {
       
   142     _WIMTRACE(_L("WIM|Scard|CScardConnector::~CScardConnector|Begin"));
       
   143     delete iTimer;
       
   144     
       
   145     //  Delete members of the parameter block
       
   146     delete iParameters.iReaderName;
       
   147     delete iParameters.iExcluded;
       
   148     delete iParameters.iATRBytes;
       
   149     delete iParameters.iAIDBytes;
       
   150 
       
   151     //  Detach from all connections
       
   152     if ( iConnections->Count() )
       
   153         {
       
   154         TConnection& connection = iConnections->At( 0 );
       
   155         //  Detach and delete all connections
       
   156         while ( iConnections->Count() )
       
   157             {
       
   158             connection = iConnections->At( 0 );
       
   159             TInt err = KErrNone;
       
   160             TRAP( err, connection.iCtrl->CancelTransmissionsL(
       
   161                                                       connection.iSessionID ) );
       
   162             connection.iCtrl->DetachSessionFromReader( connection.iSessionID );
       
   163             iConnections->Delete( 0 );
       
   164             }
       
   165         }
       
   166 
       
   167     iConnections->Reset();
       
   168     delete iConnections;
       
   169     delete iClientMessage;
       
   170     delete iStack;
       
   171     }
       
   172 
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // CScardConnector::ConnectToReaderL
       
   176 // The connection is attempted and if it is successful
       
   177 // the session requesting the connection is notified. If the connection
       
   178 // can not yet be made, this object will remain waiting until all the
       
   179 // required parameters are matched or a timeout occurs.
       
   180 // -----------------------------------------------------------------------------
       
   181 //
       
   182 void CScardConnector::ConnectToReaderL()
       
   183     {
       
   184     _WIMTRACE(_L("WIM|Scard|CScardConnector::ConnectToReaderL|Begin"));
       
   185     // Get the limit factors
       
   186     TRAPD( messageError, ReadLimitsL() ); 
       
   187     if ( messageError == KScErrBadArgument || 
       
   188         messageError == KScErrNotSupported )
       
   189         {
       
   190 #ifdef _DEBUG
       
   191         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   192             EFileLoggingModeAppend, 
       
   193             _L( "CScardConnector::ConnectToReader: ReadLimits failed: %d \n" ), 
       
   194             messageError );
       
   195 #endif
       
   196         iConnectionRegistry->ConnectDone( this, 0, messageError );
       
   197         iConnectionRegistry->RemoveConnector( this );
       
   198         delete this;
       
   199         return;
       
   200         }
       
   201     else if ( messageError != KErrNone )
       
   202         {
       
   203         User::Panic( _L( "Not enough free memory" ), KScPanicNoMemory );
       
   204         }
       
   205 
       
   206     //  Now go to all the ACs you need and attach to them. If the reader 
       
   207     //  is spesific, only one entry is required. Otherwise all are.
       
   208     if ( iParameters.iReaderName )
       
   209         {
       
   210 #ifdef _DEBUG
       
   211         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   212             EFileLoggingModeAppend, 
       
   213             _L( "CScardConnector::ConnectToReader Connecting to specific\
       
   214             reader: %S\n" ),
       
   215            iParameters.iReaderName);
       
   216 #endif
       
   217         iOneReaderMode = ETrue;
       
   218         //  Is the chosen one supported ??
       
   219         if ( !( iConnectionRegistry->Server()->ReaderSupported( 
       
   220             *iParameters.iReaderName ) ) )
       
   221             {
       
   222 #ifdef _DEBUG
       
   223             RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   224                 EFileLoggingModeAppend, 
       
   225                 _L( "CScardConnector::ConnectToReader ReaderSupported\
       
   226                 failed: \n" ) );
       
   227 #endif
       
   228             iConnectionRegistry->ConnectDone( this, 0, KScErrUnknownReader );
       
   229             iConnectionRegistry->RemoveConnector( this );
       
   230             delete this;
       
   231             return;
       
   232             }
       
   233 
       
   234         //  Grab the reader id (this shouldn't fail if the previous step 
       
   235         //  went ok)
       
   236         const TReaderID readerID = 
       
   237             iConnectionRegistry->Server()->ReaderID( *iParameters.iReaderName );
       
   238 
       
   239         //  If the reader can't be open when connecting, check it
       
   240         if ( iParameters.iNewReaderOnly )
       
   241             {
       
   242             if ( iConnectionRegistry->Server()->AccessRegistry()->
       
   243                 ReaderHandlerLoaded( readerID ) )
       
   244                 {
       
   245 #ifdef _DEBUG
       
   246                 RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   247                     EFileLoggingModeAppend, 
       
   248                     _L( "CScardConnector::ConnectToReader Failed! Only new\
       
   249                     readers allowed!\n" ) );
       
   250 #endif
       
   251                 iConnectionRegistry->ConnectDone( this, 0, 
       
   252                     KScErrAlreadyExists );
       
   253                 iConnectionRegistry->RemoveConnector( this );
       
   254                 delete this;
       
   255                 return;
       
   256                 }
       
   257             }
       
   258         //  Create the access controller and the reader
       
   259         TBool opened( EFalse );
       
   260         TRAPD( readerError, opened = NewConnectionL( (*iClientMessage), 
       
   261             readerID ) );
       
   262         
       
   263         //  If the reader object could not be created, look no further, 
       
   264         //  we're in trouble
       
   265         if ( readerError != KErrNone )
       
   266             {
       
   267 #ifdef _DEBUG
       
   268             RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   269                 EFileLoggingModeAppend, 
       
   270                 _L( "CScardConnector::ConnectToReader NewConnectionL failed:\
       
   271                 %d \n" ), readerError );
       
   272 #endif
       
   273             iConnectionRegistry->ConnectDone( this, 0, readerError );
       
   274             iConnectionRegistry->RemoveConnector( this );
       
   275             delete this;
       
   276             return;
       
   277             }
       
   278 
       
   279         //  The reader was created successfully.
       
   280 
       
   281         //  1.  If the reader is open and if old cards are acceptable, 
       
   282         //  check conditions
       
   283 
       
   284         if ( opened && !iParameters.iNewCardOnly )
       
   285             {
       
   286             TScardATR atr;
       
   287             iConnections->At( 0 ).iReader->GetATR( atr );
       
   288             const TBool ok( CheckConditions( iConnections->At( 0 ), &atr ) );
       
   289             if ( ok )
       
   290                 {
       
   291 #ifdef _DEBUG
       
   292                 RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   293                     EFileLoggingModeAppend, 
       
   294                     _L( "CScardConnector::ConnectToReader: Connection\
       
   295                     succesfully established.\n" ) );
       
   296 #endif
       
   297                 ConnectionDone( iConnections->At( 0 ).iReaderID, KErrNone );
       
   298                 return;
       
   299                 }
       
   300 #ifdef _DEBUG
       
   301             RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   302                 EFileLoggingModeAppend, 
       
   303                 _L( "CScardConnector::ConnectToReader CheckConditions\
       
   304                 failed! \n" ) );
       
   305 #endif
       
   306             }
       
   307 
       
   308         //  2.  In other cases, just stay waiting for either the OpenReader 
       
   309         //  or condition checking to go through or for a card event to occur.
       
   310         return;
       
   311         }
       
   312     else
       
   313         {
       
   314         //  Contact (almost) all readers, dead or alive...
       
   315 #ifdef _DEBUG
       
   316         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   317             EFileLoggingModeAppend, 
       
   318            _L("CScardConnector::ConnectToReader Connecting to all readers.\n") );
       
   319 #endif
       
   320         CScardReaderRegistry* rr = 
       
   321             iConnectionRegistry->Server()->ReaderRegistry();
       
   322 
       
   323         //  First list the ones not yet opened
       
   324         CArrayFixFlat<TReaderID>* closelist = NULL;
       
   325         closelist = new( ELeave ) CArrayFixFlat<TReaderID>( 1 );
       
   326         CleanupStack::PushL( closelist );
       
   327         rr->ListClosedReadersL( closelist );
       
   328 
       
   329         //  then list the ones that are currently open (if necessary)
       
   330         CArrayPtrFlat<CScardAccessControl>* openlist = NULL;
       
   331         if ( !iParameters.iNewReaderOnly )
       
   332             {
       
   333             openlist = new( ELeave ) CArrayPtrFlat<CScardAccessControl>( 1 );
       
   334             CleanupStack::PushL( openlist );
       
   335             rr->ListOpenReadersL( openlist );
       
   336             }
       
   337 
       
   338         TReaderID excludeID( -1 );
       
   339         if ( iParameters.iExcluded )
       
   340             {
       
   341 #ifdef _DEBUG
       
   342             RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   343                 EFileLoggingModeAppend, 
       
   344                _L( "CScardConnector::ConnectToReader Get ID of excluded\
       
   345                reader.\n" ) );
       
   346 #endif
       
   347             excludeID = iConnectionRegistry->Server()->ReaderID( 
       
   348                 *iParameters.iExcluded );
       
   349             }
       
   350         
       
   351         //  Attach to open readers
       
   352         if ( !iParameters.iNewReaderOnly )
       
   353             {
       
   354 #ifdef _DEBUG
       
   355             RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   356                 EFileLoggingModeAppend, 
       
   357                _L( "CScardConnector::ConnectToReader Attach to open readers" ) );
       
   358 #endif
       
   359             for ( TInt i( 0 ); i < openlist->Count(); i++ )
       
   360                 {
       
   361                 TReaderID next = openlist->At( i )->ReaderID();
       
   362                 if ( next != excludeID )
       
   363                     {
       
   364                     TBool open( EFalse );
       
   365                     //  Create the connection
       
   366                     TRAPD( readerError, 
       
   367                         open = NewConnectionL( *iClientMessage, next ) );
       
   368 
       
   369                     //  If the reader is already open and old cards are 
       
   370                     //  acceptable, check SC for the parameters.
       
   371 
       
   372                     if ( !readerError && open && !iParameters.iNewCardOnly )
       
   373                         {
       
   374                         const TInt index = iConnections->Count() - 1;
       
   375                         TScardATR atr;
       
   376                         iConnections->At( index ).iReader->GetATR( atr );
       
   377                         TBool ok = CheckConditions( iConnections->At( 
       
   378                             iConnections->Count() - 1 ), &atr );
       
   379                         if ( ok )
       
   380                             {
       
   381                             //delete openlist & closelist
       
   382                             CleanupStack::PopAndDestroy( 2 ); 
       
   383                             ConnectionDone( next, KErrNone );
       
   384                             return;
       
   385                             }
       
   386                         }
       
   387                     else if ( open && iParameters.iNewCardOnly )
       
   388                         {
       
   389                         //delete openlist & closelist
       
   390                         CleanupStack::PopAndDestroy( 2 ); 
       
   391                         // old cards are not acceptable, return error
       
   392                         ConnectionDone( next, KScErrNotFound );
       
   393                         return;
       
   394                         }    
       
   395                     }
       
   396                 }
       
   397             CleanupStack::PopAndDestroy( openlist );  //  delete openlist
       
   398             }
       
   399         
       
   400         //  attach to new readers
       
   401         for ( TInt i( 0 ); i < closelist->Count(); i++ )
       
   402             {
       
   403 #ifdef _DEBUG
       
   404             RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   405                 EFileLoggingModeAppend, 
       
   406                _L( "CScardConnector::ConnectToReader Attach to new readers" ) );
       
   407 #endif
       
   408             TReaderID next = closelist->At( i );
       
   409             if ( next != excludeID )
       
   410                 {
       
   411                 TInt err = KErrNone;
       
   412                 TRAP( err, NewConnectionL( (*iClientMessage), next ) );
       
   413                 }
       
   414             }
       
   415 
       
   416         CleanupStack::PopAndDestroy( closelist );  //  delete closelist
       
   417         }
       
   418 
       
   419     //  If no readers could be contacted at all ( == the handlers could not be 
       
   420     //  created) why continue?
       
   421     if ( !iConnections->Count() )
       
   422         {
       
   423         iState = EConnectionComplete;
       
   424         ConnectionDone( 0, KScErrNotFound );
       
   425         return;
       
   426         }
       
   427 
       
   428     if ( iConnections->Count() == 1 )
       
   429         {
       
   430         iOneReaderMode = ETrue;
       
   431         }
       
   432     }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CScardConnector::CardEvent
       
   436 // Handle card event
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 void CScardConnector::CardEvent(
       
   440     const TScardServiceStatus aEvent, 
       
   441     const TScardATR& aATR, 
       
   442     const TReaderID& aReaderID )
       
   443     {
       
   444     _WIMTRACE(_L("WIM|Scard|CScardConnector::CardEvent|Begin"));
       
   445     //  Card event handling is postponed if waiting for confirmation on
       
   446     //  a connection attempt
       
   447     if ( iState == EWaitingForConfirm )
       
   448         {
       
   449         iStack->QueueEvent( aReaderID, aEvent );
       
   450         return;
       
   451         }
       
   452 
       
   453     //  Find the connection handling the reader and see if it meets the 
       
   454     //  criteria
       
   455     TConnection* conn = NULL;
       
   456     TRAPD( err, conn = &( FindReaderConnectionL( aReaderID ) ) );
       
   457 
       
   458     //  The connection must be found...
       
   459     __ASSERT_ALWAYS( !err, User::Panic( _L( "Connector stack failure" ), 
       
   460         KScServerPanicInternalError ) );
       
   461 
       
   462     //  Now see what kind of event has occurred
       
   463     switch ( aEvent )
       
   464         {
       
   465         case EScardRemoved: // Flow through
       
   466         case EReaderRemoved:
       
   467             {
       
   468             break;
       
   469             }
       
   470         case EScardInserted:
       
   471             {
       
   472             //  A new card has been inserted, match it against the parameters
       
   473             const TBool ok = CheckConditions( *conn, &aATR );
       
   474             if ( ok )
       
   475                 {
       
   476                 ConnectionDone( conn->iReaderID, KErrNone );
       
   477                 }
       
   478             break;
       
   479             }
       
   480         default:
       
   481             {
       
   482             break;
       
   483             }
       
   484         }
       
   485     }
       
   486 
       
   487 // -----------------------------------------------------------------------------
       
   488 // CScardConnector::ReadLimitsL
       
   489 // Extract the limit parameters for this connection attempt
       
   490 // -----------------------------------------------------------------------------
       
   491 //
       
   492 void CScardConnector::ReadLimitsL()
       
   493     {
       
   494     _WIMTRACE(_L("WIM|Scard|CScardConnector::ReadLimitsL|Begin"));
       
   495     TInt limiters = (*iClientMessage).Int0();
       
   496 
       
   497     //  Check out the limiting factors
       
   498     
       
   499     //  The name of the reader is specified
       
   500     if ( limiters & KExplicitReader )
       
   501         {
       
   502         TInt desLen = (*iClientMessage).GetDesLength( 1 );
       
   503         HBufC* name = HBufC::NewL( desLen );
       
   504         CleanupStack::PushL( name );
       
   505         iParameters.iReaderName = new( ELeave ) TPtr( name->Des() );
       
   506         TRAPD( err, (*iClientMessage).ReadL( 1, *iParameters.iReaderName ) );
       
   507         if ( err != KErrNone )
       
   508             {
       
   509             (*iClientMessage).Panic( _L( "SCardServer" ), 
       
   510                 KScServerPanicBadDescriptor );
       
   511             User::Leave( KScErrBadArgument );
       
   512             }
       
   513         CleanupStack::Pop( name );
       
   514         }
       
   515 
       
   516     //  The specified must not be contacted
       
   517     else if ( limiters & KExcludedReader )
       
   518         {
       
   519         TInt desLen = (*iClientMessage).GetDesLength( 1 );
       
   520         HBufC* bytes = HBufC::NewL( desLen );
       
   521         CleanupStack::PushL( bytes );
       
   522         iParameters.iExcluded = new( ELeave ) TScardReaderName( bytes->Des() );
       
   523         TRAPD( err, (*iClientMessage).ReadL( 1, *iParameters.iExcluded ) );
       
   524         if ( err != KErrNone )
       
   525             {
       
   526             (*iClientMessage).Panic( _L( "SCardServer" ), 
       
   527                 KScServerPanicBadDescriptor );
       
   528             User::Leave( KScErrBadArgument );
       
   529             }
       
   530         CleanupStack::Pop( bytes );
       
   531         }
       
   532 
       
   533     //  Only newly inserted cards are acceptable
       
   534     if ( limiters & KNewReadersOnly )
       
   535         {
       
   536         iParameters.iNewReaderOnly = ETrue;
       
   537         }
       
   538 
       
   539     //  The ATR bytes of the card are spesified
       
   540     if ( limiters & KATRSpesified )
       
   541         {
       
   542         User::Leave( KScErrNotSupported );
       
   543         }
       
   544 
       
   545     //  The spesified application must be located within the SC
       
   546     else if ( limiters & KApplicationSpesified )
       
   547         {
       
   548         User::Leave( KScErrNotSupported );
       
   549         }
       
   550 
       
   551     //  Only newly inserted cards are acceptable
       
   552     if ( limiters & KNewCardsOnly )
       
   553         {
       
   554         iParameters.iNewCardOnly = ETrue;
       
   555         }
       
   556 
       
   557     //  Is there a time limit as well ?
       
   558     TInt32 timeOut = reinterpret_cast< TInt32 >( iClientMessage->Ptr3() );
       
   559 
       
   560     if ( timeOut )
       
   561         {
       
   562         iTimer = CScardConnectionTimer::NewL( this, timeOut );
       
   563         }
       
   564     }
       
   565 
       
   566 // -----------------------------------------------------------------------------
       
   567 // CScardConnector::CheckConditions
       
   568 // Check if connection conditions are met.
       
   569 // -----------------------------------------------------------------------------
       
   570 //
       
   571 TBool CScardConnector::CheckConditions(
       
   572     TConnection& /*aConnection*/, 
       
   573     const TScardATR* aATR )
       
   574     {
       
   575     _WIMTRACE(_L("WIM|Scard|CScardConnector::CheckConditions|Begin"));
       
   576     //  If no parameters are spesified, announce a match
       
   577     if ( !(iParameters.iATRBytes || iParameters.iAIDBytes ) )
       
   578         {
       
   579 #ifdef _DEBUG
       
   580         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   581             EFileLoggingModeAppend, 
       
   582             _L( "CScardConnector::CheckConditions: no parameters\
       
   583             specified.\n" ) );
       
   584 #endif
       
   585 
       
   586         iState = EConnectionComplete;
       
   587         return ETrue;
       
   588         }
       
   589 
       
   590     //  Now check the parameters one by one
       
   591 
       
   592     //  ATR match ?
       
   593     if ( iParameters.iATRBytes )
       
   594         {
       
   595         if ( aATR )
       
   596             {
       
   597             if ( *iParameters.iATRBytes == *aATR )
       
   598                 {
       
   599 #ifdef _DEBUG
       
   600                 RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   601                     EFileLoggingModeAppend, 
       
   602                     _L( "CScardConnector::CheckConditions: ATR match." ) );
       
   603 #endif
       
   604 
       
   605                 iState = EConnectionComplete;
       
   606                 return ETrue;
       
   607                 }
       
   608             }
       
   609 #ifdef _DEBUG
       
   610         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   611             EFileLoggingModeAppend, 
       
   612             _L( "CScardConnector::CheckConditions: ATR mismatch!\n" ) );
       
   613 #endif
       
   614 
       
   615         return EFalse;
       
   616         }
       
   617 
       
   618     //  The card has the requiered application ?
       
   619     else if ( iParameters.iAIDBytes )
       
   620         {
       
   621 #ifdef _DEBUG
       
   622         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,     
       
   623             EFileLoggingModeAppend, 
       
   624             _L( "CScardConnector::CheckConditions: AIDBytes not supported!\n" ) );
       
   625 #endif
       
   626         return EFalse;
       
   627         }
       
   628     return EFalse;
       
   629     }
       
   630 
       
   631 // -----------------------------------------------------------------------------
       
   632 // CScardConnector::NewConnectionL
       
   633 // Create new connection to the reader.
       
   634 // -----------------------------------------------------------------------------
       
   635 //
       
   636 TBool CScardConnector::NewConnectionL(
       
   637     const RMessage2 aMessage, 
       
   638     const TReaderID aReaderID )
       
   639     {
       
   640     _WIMTRACE(_L("WIM|Scard|CScardConnector::NewConnectionL|Begin"));
       
   641     TConnection conn;
       
   642 
       
   643     conn.iReaderID = aReaderID;
       
   644 
       
   645     //  Assign an access controller to this connection
       
   646     conn.iCtrl = iConnectionRegistry->Server()->AccessRegistry()->
       
   647         AccessController( aReaderID );
       
   648     
       
   649     //  Make sure there was enough memory for the access controller
       
   650     __ASSERT_MEMORY( !(conn.iCtrl) );
       
   651 
       
   652     //  attempt to create the connection's reader
       
   653     TRAPD( readerError, conn.iReader = conn.iCtrl->AttachSessionToReaderL( 
       
   654         this, conn.iSessionID ) );
       
   655 
       
   656     //  If creating the reader succeeds, attempt to initialise the reader
       
   657     if ( readerError == KErrNone )
       
   658         {
       
   659 #ifdef _DEBUG    
       
   660         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   661             EFileLoggingModeAppend, 
       
   662             _L( "CScardConnector::NewConnectionL: Reader (ID: %d)\
       
   663             succesfully created.\n" ), aReaderID );
       
   664 #endif
       
   665         const TBool ok( conn.iCtrl->InitialiseReader( conn.iSessionID, 
       
   666             aMessage ) );
       
   667         iConnections->AppendL( conn );
       
   668         return ok;
       
   669         }
       
   670 
       
   671 #ifdef _DEBUG
       
   672     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName,         
       
   673         EFileLoggingModeAppend, 
       
   674         _L( "CScardConnector::NewConnectionL: FAILED! error: %d\n" ),
       
   675         readerError );
       
   676 #endif
       
   677 
       
   678     conn.iCtrl->DetachSessionFromReader( conn.iSessionID );
       
   679     User::Leave( readerError );
       
   680     return EFalse;
       
   681     }
       
   682 
       
   683 // -----------------------------------------------------------------------------
       
   684 // CScardConnector::FindReaderConnectionL
       
   685 // Find connection for given reader.
       
   686 // -----------------------------------------------------------------------------
       
   687 //
       
   688 TConnection& CScardConnector::FindReaderConnectionL(
       
   689     const TReaderID& aReaderID )
       
   690     {
       
   691     _WIMTRACE(_L("WIM|Scard|CScardConnector::FindReaderConnectionL|Begin"));
       
   692     TInt count = iConnections->Count();
       
   693     for ( TInt i( 0 ); i < count; i++ )
       
   694         {
       
   695         if ( iConnections->At( i ).iReaderID == aReaderID )
       
   696             {
       
   697             return iConnections->At( i );
       
   698             }
       
   699         }
       
   700     User::Leave( KScErrNotFound );
       
   701     return iConnections->At( 0 ); //just to satisfy compiler
       
   702     }
       
   703 
       
   704 // -----------------------------------------------------------------------------
       
   705 // CScardConnector::ConnectionDone
       
   706 // Connection has been established. Remove connector.
       
   707 // -----------------------------------------------------------------------------
       
   708 //
       
   709 void CScardConnector::ConnectionDone(
       
   710     const TReaderID aReaderID, 
       
   711     const TInt& aErrorCode )
       
   712     {
       
   713     _WIMTRACE(_L("WIM|Scard|CScardConnector::ConnectionDone|Begin"));
       
   714 #ifdef _DEBUG
       
   715     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   716         EFileLoggingModeAppend, _L( "CScardConnector::ConnectionDone \
       
   717         status: %d \n" ), aErrorCode );
       
   718 #endif
       
   719     if ( aErrorCode != KErrNone )
       
   720         {
       
   721         iState = EConnectionComplete;
       
   722         }
       
   723     if ( iTimer )
       
   724         {
       
   725 #ifdef _DEBUG
       
   726         RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   727             EFileLoggingModeAppend, _L( "CScardConnector::ConnectionDone Cancel\
       
   728             timer. \n" ) );
       
   729 #endif
       
   730         iTimer->Cancel();
       
   731         }
       
   732 
       
   733     if ( aErrorCode == KScErrTimeOut )
       
   734         {
       
   735         iConnectionRegistry->Server()->
       
   736             FindAccessControl( aReaderID )->Cancel();
       
   737       
       
   738         }
       
   739 
       
   740     iConnectionRegistry->ConnectDone( this, aReaderID, aErrorCode );
       
   741     if ( iState == EConnectionComplete )
       
   742         {
       
   743         iConnectionRegistry->RemoveConnector( this );
       
   744         delete this;
       
   745         }
       
   746     }
       
   747 
       
   748 // -----------------------------------------------------------------------------
       
   749 // CScardConnector::Cancel
       
   750 // Cancel connection. Call ConnectionDone with error code KScErrCancelled.
       
   751 // -----------------------------------------------------------------------------
       
   752 //
       
   753 void CScardConnector::Cancel()
       
   754     {
       
   755     _WIMTRACE(_L("WIM|Scard|CScardConnector::Cancel|Begin"));
       
   756     iState = EConnectionComplete;
       
   757     ConnectionDone( 0, KScErrCancelled );
       
   758     }
       
   759 
       
   760 // -----------------------------------------------------------------------------
       
   761 // CScardConnector::Message
       
   762 // Return client message.
       
   763 // -----------------------------------------------------------------------------
       
   764 //
       
   765 RMessage2& CScardConnector::Message()
       
   766     {
       
   767     _WIMTRACE(_L("WIM|Scard|CScardConnector::Message|Begin"));
       
   768     return *iClientMessage;
       
   769     }
       
   770 
       
   771 // -----------------------------------------------------------------------------
       
   772 // CScardConnector::ConnectionTimedOut
       
   773 // Timeout has occurred. Connectin done with KScErrTimeOut.
       
   774 // -----------------------------------------------------------------------------
       
   775 //
       
   776 void CScardConnector::ConnectionTimedOut()
       
   777     {
       
   778     _WIMTRACE(_L("WIM|Scard|CScardConnector::ConnectionTimedOut|Begin"));
       
   779 #ifdef _DEBUG
       
   780     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   781         EFileLoggingModeAppend, 
       
   782         _L( "CScardConnector::ConnectionTimedOut state=%d\n" ), iState );
       
   783 #endif
       
   784     if ( iState == EWaitingForConfirm )
       
   785         {
       
   786         iState = ETimedOut;
       
   787         return;
       
   788         }
       
   789     else
       
   790         {
       
   791         iState = EConnectionComplete;
       
   792         ConnectionDone( iConnections->At( 0 ).iReaderID, KScErrTimeOut );
       
   793         }
       
   794     }
       
   795 
       
   796 //  End of File