wim/SwimReader/src/SwimReader.cpp
changeset 0 164170e6151a
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:  Implements the functional and communication levels of module
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES 
       
    20 #include    "SwimReader.h"
       
    21 #include    "SwimReaderIF.h"
       
    22 #include    "rmmcustomapi.h"    // TApdu
       
    23 #include    "WimTrace.h"        // For trace logging
       
    24 #include    <mmtsy_names.h>     // TSY and Phone name
       
    25 
       
    26 #ifdef _DEBUG
       
    27 #include    <flogger.h>
       
    28 #endif
       
    29 
       
    30 // ============================ MEMBER FUNCTIONS ===============================
       
    31 
       
    32 // -----------------------------------------------------------------------------
       
    33 // CSwimReader::NewL
       
    34 // Two-phased constructor.
       
    35 // -----------------------------------------------------------------------------
       
    36 //
       
    37 CSwimReader* CSwimReader::NewL( CSwimReaderIF* aInterface )
       
    38     {
       
    39     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::NewL|Begin"));
       
    40     CSwimReader* self = new( ELeave ) CSwimReader( aInterface );
       
    41     CleanupStack::PushL( self );
       
    42     self->ConstructL();
       
    43     CleanupStack::Pop( self );
       
    44 
       
    45     return self;
       
    46     }
       
    47 
       
    48 // -----------------------------------------------------------------------------
       
    49 // CSwimReader::CSwimReader
       
    50 // C++ default constructor can NOT contain any code, that
       
    51 // might leave.
       
    52 // -----------------------------------------------------------------------------
       
    53 //
       
    54 CSwimReader::CSwimReader( CSwimReaderIF* aInterface )
       
    55     : CActive( EPriorityNormal )
       
    56     {
       
    57     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::CSwimReader|Begin"));
       
    58     CActiveScheduler::Add( this );
       
    59     iInterface = aInterface;
       
    60     iReaderAttached = ETrue;
       
    61     
       
    62     // Currently (and probably always) APDU interface and forecoming
       
    63     // APDU server will support only one reader, which number is 0.
       
    64     iPreferredReader = 0;
       
    65     }
       
    66 
       
    67 // -----------------------------------------------------------------------------
       
    68 // CSwimReader::ConstructL
       
    69 // Symbian 2nd phase constructor can leave.
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 void CSwimReader::ConstructL()
       
    73     {
       
    74     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::ConstructL|Begin"));
       
    75 #ifdef _DEBUG        
       
    76     RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,     
       
    77         EFileLoggingModeAppend, 
       
    78         _L( "CSwimReader::ConstructL: Creating new RTelServer object...\n" ) );
       
    79 #endif
       
    80     iEtelServer = new( ELeave ) RTelServer();    
       
    81     }
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CSwimReader:: ~CSwimReader
       
    85 // Destructor
       
    86 // -----------------------------------------------------------------------------
       
    87 //
       
    88 CSwimReader::~CSwimReader()
       
    89     {
       
    90     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::~CSwimReader|Begin"));
       
    91     Close();
       
    92     CleanUp();
       
    93     delete iMsg;
       
    94     delete iEtelServer;
       
    95     delete iTempBuf;
       
    96     }
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 // CSwimReader::APDUReqL
       
   100 // Send APDU command aCommandAPDU to the ETEL server.
       
   101 // Response is set to aResponseAPDU.
       
   102 // -----------------------------------------------------------------------------
       
   103 //
       
   104 void CSwimReader::APDUReqL(
       
   105     TRequestStatus& aStatus,
       
   106     const TPtrC8&   aCommandAPDU,
       
   107     TPtr8&          aResponseAPDU,    
       
   108     TUint8          aServiceType,
       
   109     TUint8          aCardReader,
       
   110     TUint8          aAppType,
       
   111     TUint8          aPaddingByte )
       
   112     {
       
   113     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::APDUReqL1|Begin"));
       
   114     iClientStatus = &aStatus;
       
   115     aStatus = KRequestPending;
       
   116     APDUReqL( aCommandAPDU, aResponseAPDU, aServiceType, aCardReader, 
       
   117               aAppType, aPaddingByte );
       
   118     iPhase = EAPDURequest;
       
   119     SetActive();
       
   120     }
       
   121 
       
   122 // -----------------------------------------------------------------------------
       
   123 // CSwimReader::Close
       
   124 // Close ETEL connection and connection to CustomAPI.
       
   125 // -----------------------------------------------------------------------------
       
   126 //
       
   127 void CSwimReader::Close()
       
   128     {
       
   129     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::Close|Begin"));
       
   130     Cancel();
       
   131     if ( iOpen )
       
   132         {
       
   133         iApdu.Close();
       
   134         iEtelServer->Close();
       
   135         iOpen = EFalse;
       
   136         }
       
   137     }
       
   138     
       
   139 // -----------------------------------------------------------------------------
       
   140 // CSwimReader::DoCancel
       
   141 // Asynchronous request cancelled
       
   142 // -----------------------------------------------------------------------------
       
   143 //
       
   144 void CSwimReader::DoCancel()
       
   145     {
       
   146     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::DoCancel|Begin"));
       
   147     
       
   148     if( iPhase == EAPDURequest )
       
   149         {
       
   150     	iApdu.CancelAPDUReq();
       
   151         }
       
   152         
       
   153 #ifdef _DEBUG            
       
   154     RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,         
       
   155         EFileLoggingModeAppend, 
       
   156         _L( "CSwimReader::DoCancel: Clean up.\n" ) );
       
   157 #endif
       
   158     CleanUp();
       
   159 #ifdef _DEBUG            
       
   160     RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,         
       
   161         EFileLoggingModeAppend, 
       
   162         _L( "CSwimReader::DoCancel: Complete request with status %d.\n" ),
       
   163             iStatus.Int() );
       
   164 #endif
       
   165     User::RequestComplete( iClientStatus, iStatus.Int() );
       
   166 
       
   167     }
       
   168 
       
   169 // -----------------------------------------------------------------------------
       
   170 // CSwimReader::PreferredReaderStatus
       
   171 // Get preferred reader statuses from the iPreferredReaderStatus member.
       
   172 // -----------------------------------------------------------------------------
       
   173 //
       
   174 void CSwimReader::PreferredReaderStatus( TUint8& aReaderStatus )
       
   175     {
       
   176     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::PreferredReaderStatus|Begin"));
       
   177     aReaderStatus = iPreferredReaderStatus;
       
   178     }
       
   179 
       
   180 // -----------------------------------------------------------------------------
       
   181 // CSwimReader::SelectCardReader
       
   182 // From given status bytes, select a card reader, which
       
   183 // is present and card is also present in the reader.
       
   184 // -----------------------------------------------------------------------------
       
   185 //
       
   186 TUint8 CSwimReader::SelectCardReader(
       
   187     TDesC8&  aReaderStatuses,
       
   188     TUint8& aPreferredReaderStatus,
       
   189     TUint8  aOldPreferredReader /* = NO_PREFERRED_READER */ )
       
   190     {
       
   191     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::SelectCardReader|Begin"));
       
   192     TInt i;
       
   193     TInt size;
       
   194     TUint8 readerStatus;
       
   195 
       
   196     size = aReaderStatuses.Length();
       
   197 
       
   198     for ( i = 0; i < size; i++ )
       
   199         {
       
   200         readerStatus = aReaderStatuses[i];
       
   201 
       
   202         _WIMTRACE2(_L("WIM|SwimReader|CSwimReader::SelectCardReader|ReaderStatus=%d"), 
       
   203             (TUint8)aReaderStatuses[i]);
       
   204 
       
   205         // First check that this isn't the reader the caller has
       
   206         // already tried to use and find inappropriate for some reason.
       
   207         if ( i != aOldPreferredReader )
       
   208             {
       
   209             // If reader and card are present, this reader is good for us.
       
   210             if ( (readerStatus & KCardReaderPresent) &&
       
   211                 (readerStatus & KCardPresent) )
       
   212                 {
       
   213                 aPreferredReaderStatus = readerStatus;
       
   214                 _WIMTRACE2(_L("WIM|SwimReader|CSwimReader::SelectCardReader|PreferredReaderStatus1=%d"),
       
   215                     readerStatus);
       
   216 
       
   217                 // Reader number is stored in first three bits,
       
   218                 // so return only them.
       
   219                 return ( static_cast< TUint8 >( readerStatus & KIdentityMask ) );
       
   220                 }
       
   221             }
       
   222         }
       
   223 
       
   224     // If not found, use a one where reader is present.
       
   225     for ( i = 0; i < size; i++ )
       
   226         {
       
   227         readerStatus = aReaderStatuses[i];
       
   228 
       
   229         // First check that this isn't the reader the caller has
       
   230         // already tried to use and find inappropriate for some reason.
       
   231         if ( i != aOldPreferredReader )
       
   232             {
       
   233             // If reader is present, this reader is good for us.
       
   234             if ( readerStatus & KCardReaderPresent )
       
   235                 {
       
   236                 _WIMTRACE2(_L("WIM|SwimReader|CSwimReader::SelectCardReader|PreferredReaderStatus2=%d"),
       
   237                     readerStatus);
       
   238                 aPreferredReaderStatus = readerStatus;
       
   239 
       
   240                 // Reader number is stored in first three bits,
       
   241                 // so return only them.
       
   242                 return ( static_cast< TUint8 >( readerStatus & KIdentityMask ) );
       
   243                 }
       
   244             }
       
   245         }
       
   246 
       
   247     // If nothing found, return a one caller gave to us.
       
   248     return aOldPreferredReader;
       
   249     }
       
   250 
       
   251 // -----------------------------------------------------------------------------
       
   252 // CSwimReader::SetCardInserted
       
   253 // Set card inserted
       
   254 // -----------------------------------------------------------------------------
       
   255 //
       
   256 void CSwimReader::SetCardInserted( TBool aIsInserted )
       
   257     {
       
   258     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::SetCardInserted|Begin"));
       
   259     iCardInserted = aIsInserted;
       
   260     }
       
   261 
       
   262 // -----------------------------------------------------------------------------
       
   263 // CSwimReader::WakeUpL
       
   264 // Initializes the reader. Also make APDU_LIST to get
       
   265 // all statuses of card readers attached to the device.
       
   266 // -----------------------------------------------------------------------------
       
   267 //
       
   268 void CSwimReader::WakeUpL( TRequestStatus& aStatus, TDes8& aHistoricals )
       
   269     {
       
   270     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::WakeUpL|Begin"));
       
   271     iHistoricals = aHistoricals;
       
   272     iClientStatus = &aStatus;
       
   273     aStatus = KRequestPending;
       
   274 
       
   275     // Set reader not open
       
   276     iOpen = EFalse;
       
   277 
       
   278     _WIMTRACE2(_L("WIM|SwimReader|CSwimReader::WakeUpL|iPreferredReader=%d"),
       
   279         iPreferredReader);
       
   280 
       
   281     // If WakeUp failed last time, preferred reader might be initialized
       
   282     // wrong, use reader 0
       
   283     if ( iPreferredReader == KNoPreferredReader )
       
   284         {
       
   285         iPreferredReader = 0;
       
   286         _WIMTRACE(_L("WIM|SwimReader|CSwimReader::WakeUpL|iPreferredReader changed to 0"));
       
   287         }
       
   288     
       
   289     TInt ret = 0;
       
   290 
       
   291     // Connect to the Etel server.
       
   292     ret = iEtelServer->Connect();
       
   293     if ( ret != KErrNone )
       
   294         {
       
   295 #ifdef _DEBUG        
       
   296         RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,
       
   297             EFileLoggingModeAppend, 
       
   298             _L( "CSwimReader::WakeUpL: connection to etel server failed: %d" ),
       
   299             ret );
       
   300 #endif
       
   301         User::Leave( ret );
       
   302         }
       
   303 
       
   304     // Load phone module.
       
   305     ret = iEtelServer->LoadPhoneModule( KMmTsyModuleName );
       
   306     
       
   307     if ( ret != KErrNone )
       
   308         {
       
   309 #ifdef _DEBUG        
       
   310         RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,
       
   311             EFileLoggingModeAppend, 
       
   312             _L( "CSwimReader::WakeUpL: loading phone module failed: %d" ), 
       
   313             ret );
       
   314 #endif
       
   315         User::Leave( ret );
       
   316         }
       
   317 
       
   318     // Open CustomAPI connection
       
   319     ret = iApdu.Open( *iEtelServer, KMmTsyPhoneName );
       
   320 
       
   321     if ( ret != KErrNone )
       
   322         {
       
   323 #ifdef _DEBUG        
       
   324         RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,
       
   325             EFileLoggingModeAppend, 
       
   326             _L( "CSwimReader::WakeUpL: phone open failed: %d" ), 
       
   327             ret );
       
   328 #endif
       
   329         iEtelServer->Close();
       
   330         User::Leave( ret );
       
   331         }
       
   332 
       
   333     // Make LIST to get status of only available reader.
       
   334     if ( iReaderStatuses )
       
   335         {
       
   336         delete iReaderStatuses;
       
   337         iReaderStatuses = NULL;
       
   338         }
       
   339     if ( iReaderStatusesPtr )
       
   340         {
       
   341         delete iReaderStatusesPtr;
       
   342         iReaderStatusesPtr = NULL;
       
   343         }
       
   344     iReaderStatuses = HBufC8::NewL( KMaxReaderAmount );
       
   345     iReaderStatusesPtr = new ( ELeave ) TPtr8( iReaderStatuses->Des() );
       
   346 
       
   347 #ifdef _DEBUG        
       
   348         RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,
       
   349             EFileLoggingModeAppend, 
       
   350             _L( "CSwimReader::WakeUpL: Getting list..." ) );
       
   351 #endif
       
   352     _WIMTRACE2(_L("WIM|SwimReader|CSwimReader::WakeUpL|iPreferredReader=%d"),
       
   353         iPreferredReader);
       
   354 
       
   355     TRAPD( err, APDUReqL( iCmdBytes, *iReaderStatusesPtr, KList,
       
   356                           iPreferredReader ) );
       
   357 
       
   358     if ( err )
       
   359         {
       
   360 #ifdef _DEBUG        
       
   361         RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,
       
   362             EFileLoggingModeAppend, 
       
   363             _L( "CSwimReader::WakeUpL: get list failed: %d" ), err );
       
   364 #endif
       
   365         iInterface->Notify( EReaderRemoved );
       
   366         iApdu.Close();
       
   367         iEtelServer->Close();
       
   368         User::RequestComplete( iClientStatus, err );
       
   369         }
       
   370     else
       
   371         {
       
   372         _WIMTRACE2(_L("WIM|SwimReader|CSwimReader::WakeUpL|*iReaderStatusesPtr=%d"),
       
   373             *iReaderStatusesPtr);
       
   374         iPhase = EWakeUpAPDURequest;
       
   375         SetActive();
       
   376         }
       
   377     }
       
   378 
       
   379 // -----------------------------------------------------------------------------
       
   380 // CSwimReader::APDUReqL
       
   381 // Send APDU command aCommandAPDU to the ETEL server.
       
   382 // Response is set to aResponseAPDU.
       
   383 // -----------------------------------------------------------------------------
       
   384 //
       
   385 void CSwimReader::APDUReqL(
       
   386     const TPtrC8& aCommandAPDU,
       
   387     TPtr8&        aResponseAPDU,    
       
   388     TUint8        aServiceType,
       
   389     TUint8        aCardReader,
       
   390     TUint8        aAppType,
       
   391     TUint8        aPaddingByte )
       
   392     {
       
   393     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::CSwimReaderLauncher|Begin"));
       
   394     // If reader not given, use preferred reader,
       
   395     if ( aCardReader == KNoPreferredReader )
       
   396         {
       
   397         // If preferred reader is not set, quess 0.
       
   398         if ( iPreferredReader != KNoPreferredReader )
       
   399             {
       
   400             aCardReader = iPreferredReader;
       
   401             }
       
   402         else
       
   403             {
       
   404             aCardReader = 0;
       
   405             }
       
   406         }
       
   407 
       
   408     iHeader.SetHeader( aServiceType, aCardReader, aAppType, aPaddingByte );
       
   409 
       
   410     // ...and call next function.
       
   411     APDUReqL( aCommandAPDU, aResponseAPDU, iHeader );
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CSwimReader::APDUReqL
       
   416 // Send APDU command aCommandAPDU to the ETEL server.
       
   417 // Response is set to aResponseAPDU.
       
   418 // -----------------------------------------------------------------------------
       
   419 //
       
   420 void CSwimReader::APDUReqL(
       
   421     const TPtrC8&       aCommandAPDU,
       
   422     TPtr8&              aResponseAPDU,
       
   423     TSwimApduReqHeader& aReqHeader )
       
   424     {
       
   425     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::APDUReqL|Begin"));
       
   426     iReqHeader = &aReqHeader;
       
   427     iResponseAPDU = &aResponseAPDU; 
       
   428     iTempBuf = 0;
       
   429     
       
   430     if ( iMsg )
       
   431     {
       
   432     delete iMsg;
       
   433     iMsg = NULL;	
       
   434     }
       
   435     
       
   436     iMsg = new( ELeave ) RMmCustomAPI::TApdu();   
       
   437  
       
   438     // Set APDU header to APDU message.
       
   439     iMsg->iInfo = aReqHeader.Data();
       
   440 
       
   441     // Copy command APDU to response APDU and use it to both
       
   442     // transfer request to lower levels and to receive response.
       
   443     if ( &aCommandAPDU )
       
   444         {
       
   445         iMaxLen = aResponseAPDU.MaxLength();
       
   446 
       
   447         if ( iMaxLen >= aCommandAPDU.Length() )
       
   448             {
       
   449             aResponseAPDU = aCommandAPDU;
       
   450 
       
   451             iMsg->iData = &aResponseAPDU;
       
   452             }
       
   453         else
       
   454             {
       
   455             // Response APDU isn't long enough for Command APDU,
       
   456             // which makes a situation a little more complicated.
       
   457             // Create a new buffer with enough space.
       
   458             if( iTempBuf )
       
   459             {
       
   460             delete iTempBuf;
       
   461             iTempBuf = NULL;
       
   462             }
       
   463             if( iTempPtr )
       
   464             {
       
   465             delete iTempPtr;
       
   466             iTempPtr = NULL;
       
   467             }
       
   468             
       
   469 	    iTempBuf = HBufC8::NewL( aCommandAPDU.Length() );
       
   470             iTempPtr = new( ELeave )TPtr8( iTempBuf->Des() );
       
   471 	    iTempPtr->Copy( aCommandAPDU );
       
   472 	    iMsg->iData = iTempPtr;
       
   473             }
       
   474         }
       
   475     iApdu.APDUReq( iStatus, *iMsg );
       
   476     }
       
   477 
       
   478 // -----------------------------------------------------------------------------
       
   479 // CSwimReader::CleanUp
       
   480 // Clean up allocated buffers
       
   481 // -----------------------------------------------------------------------------
       
   482 //
       
   483 void CSwimReader::CleanUp()
       
   484     {
       
   485     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::CleanUp|Begin"));
       
   486     delete iReaderStatusesPtr;
       
   487     iReaderStatusesPtr = NULL;
       
   488     delete iReaderStatuses;
       
   489     iReaderStatuses = NULL;
       
   490     delete iTempBuf;
       
   491     iTempBuf = NULL;
       
   492     delete iMsg;
       
   493     iMsg = NULL;
       
   494     delete iTempPtr;
       
   495     iTempPtr = NULL;
       
   496     }
       
   497 
       
   498 // -----------------------------------------------------------------------------
       
   499 // CSwimReader::RunL
       
   500 // Handle asyncronous APDU requests
       
   501 // -----------------------------------------------------------------------------
       
   502 //
       
   503 void CSwimReader::RunL()
       
   504     {
       
   505     _WIMTRACE3(_L("WIM|SwimReader|CSwimReader::RunL|iPhase=%d, iStatus=%d"),
       
   506         iPhase, iStatus.Int() );
       
   507 
       
   508     if ( iStatus.Int() == 0 )
       
   509         {
       
   510         switch ( iPhase )
       
   511             {
       
   512             case EWakeUpAPDURequest:
       
   513                 {
       
   514                 TInt error = HandleOpenAPDUReq();
       
   515 
       
   516                 iOpen = ETrue;
       
   517 #ifdef _DEBUG        
       
   518                 RFileLogger::WriteFormat( KSwimReaderLogDir, 
       
   519                     KSwimReaderLogFileName, EFileLoggingModeAppend, 
       
   520                     _L( "CSwimReader::RunL: WakeUp completed: %d" ), 
       
   521                     error );
       
   522 #endif
       
   523 
       
   524                 User::RequestComplete( iClientStatus, error );
       
   525 
       
   526                 break;
       
   527                 }
       
   528             case EAPDURequest:
       
   529                 {
       
   530                 TInt error = HandleAPDUReq();
       
   531 
       
   532 #ifdef _DEBUG        
       
   533                 RFileLogger::WriteFormat( KSwimReaderLogDir, 
       
   534                     KSwimReaderLogFileName, EFileLoggingModeAppend, 
       
   535                     _L( "CSwimReader::RunL: APDU request completed: %d" ), 
       
   536                     error );
       
   537 #endif
       
   538                 User::RequestComplete( iClientStatus, error );
       
   539                 break;
       
   540                 }
       
   541 
       
   542             }
       
   543         }
       
   544     else
       
   545         {
       
   546 #ifdef _DEBUG                
       
   547         RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,
       
   548             EFileLoggingModeAppend, 
       
   549             _L( "CSwimReader::RunL: Error, iPhase: %d iStatus: %d" ),
       
   550             iPhase, iStatus.Int() );
       
   551 #endif
       
   552         iApdu.Close();
       
   553         iEtelServer->Close();
       
   554         CleanUp();
       
   555         User::RequestComplete( iClientStatus, iStatus.Int() );
       
   556         }
       
   557     }
       
   558 
       
   559 // -----------------------------------------------------------------------------
       
   560 // CSwimReader::HandleAPDUReq
       
   561 // Handle APDU responses
       
   562 // -----------------------------------------------------------------------------
       
   563 //
       
   564 TInt CSwimReader::HandleAPDUReq()
       
   565     {
       
   566     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::HandleAPDUReq|Begin"));
       
   567     TInt retValue;
       
   568 
       
   569     delete iMsg;
       
   570     iMsg = NULL;
       
   571 
       
   572     // If we had to use temp buffer, copy response from
       
   573     // temp buffer to response buffer given by a caller.
       
   574     if ( iTempBuf != 0 )
       
   575         {
       
   576         iMaxLen = iResponseAPDU->MaxLength();
       
   577 
       
   578         if ( iMaxLen >= iTempBuf->Length() )
       
   579             {
       
   580             *iResponseAPDU = iTempBuf->Des();
       
   581             }
       
   582         else
       
   583             {
       
   584             *iResponseAPDU = iTempBuf->Left( iMaxLen );
       
   585             }
       
   586 
       
   587         delete iTempBuf;
       
   588         }
       
   589 
       
   590     // Create TSwimApduRespHeader from response info.
       
   591     TSwimApduRespHeader respHeader( *(iReqHeader->Data()) );
       
   592 
       
   593     // Get APDU status from response header...
       
   594     iApduStatus = respHeader.Status();
       
   595 
       
   596 #ifdef _DEBUG        
       
   597     RFileLogger::WriteFormat( KSwimReaderLogDir, KSwimReaderLogFileName,
       
   598         EFileLoggingModeAppend, 
       
   599         _L( "CSwimReader::HandleAPDUReq: response status: %d" ),
       
   600         iApduStatus );
       
   601 
       
   602     RFileLogger::HexDump( KSwimReaderLogDir, KSwimReaderLogFileName,
       
   603         EFileLoggingModeAppend, 
       
   604         _S( "CSwimReader:: HandleAPDUReq APDU received:\n" ), 0,
       
   605         iResponseAPDU->Ptr(), iResponseAPDU->Length() );
       
   606 #endif
       
   607 
       
   608     // ...and switch it to SCard error codes.
       
   609     switch ( iApduStatus )
       
   610         {
       
   611         case KApduOK:
       
   612         case KErrNone: // Accept also KErrNone
       
   613             {
       
   614             retValue = KErrNone;
       
   615             break;
       
   616             }
       
   617         case KApduTransmissionError:
       
   618             {
       
   619             retValue = KScReaderErrCommunicationFailure;
       
   620             break;
       
   621             }
       
   622         case KApduCardMute:
       
   623             {
       
   624             retValue = KScReaderErrResponseTimeout;
       
   625             break;
       
   626             }
       
   627         case KApduCardDisconnected:
       
   628             {
       
   629             retValue = KScReaderErrNoCard;
       
   630             break;
       
   631             }
       
   632         case KApduError:
       
   633             {
       
   634             retValue = KScReaderErrCardFailure;
       
   635             break;
       
   636             }
       
   637         case KApduReaderNotValid:
       
   638             {
       
   639             retValue = KScReaderErrNoReader;
       
   640             break;
       
   641             }
       
   642         case KApduFormatError:
       
   643             {
       
   644             retValue = KScErrBadArgument;
       
   645             break;
       
   646             }
       
   647         case KApduTypeNotValid:
       
   648             {
       
   649             retValue = KScErrBadArgument;
       
   650             break;
       
   651             }
       
   652         // DOS SIM server errors
       
   653         case KSimServError:
       
   654         case KSimServNotready:
       
   655         case KSimServNoservice:
       
   656             {
       
   657             retValue = KScReaderErrReaderFailure;
       
   658             break;
       
   659             }
       
   660         default:
       
   661             retValue = KScErrUnknown;
       
   662             break;
       
   663         }
       
   664 
       
   665         // Check actual length of the data received and compare it to
       
   666         // the length of the response buffer allocated by the caller.
       
   667         if ( respHeader.DataLength() > iResponseAPDU->MaxLength() 
       
   668              && !retValue )
       
   669             {
       
   670             // If there was more data than fitted to the buffer, tell to the 
       
   671             // caller that the buffer was insufficient.
       
   672             retValue = KScErrInsufficientBuffer;
       
   673             }
       
   674         _WIMTRACE2(_L("WIM|SwimReader|CSwimReader::HandleAPDUReq|return %d"),
       
   675             retValue);
       
   676         return retValue;
       
   677     }
       
   678 
       
   679 // -----------------------------------------------------------------------------
       
   680 // CSwimReader::HandleOpenAPDUReq
       
   681 // Handle APDU request for GetReaderList request 
       
   682 // -----------------------------------------------------------------------------
       
   683 //
       
   684 TInt CSwimReader::HandleOpenAPDUReq()
       
   685     {
       
   686     _WIMTRACE(_L("WIM|SwimReader|CSwimReader::HandleOpenAPDUReq|Begin"));
       
   687     TInt error = HandleAPDUReq();
       
   688 
       
   689     if ( error == KErrNone )
       
   690         {
       
   691         // Select one reader, which looks like a most promising
       
   692         // candidate to contain something useful.
       
   693         iPreferredReader = SelectCardReader( *iReaderStatuses, 
       
   694                                              iPreferredReaderStatus );
       
   695         }
       
   696     return error;
       
   697     }
       
   698 
       
   699 // End of File