wim/Scard/src/ScardComm.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:  Core class for all Smart Card aware applications to use when 
       
    15 *                communicating with the card.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include    "Scard.h"
       
    23 #include    "ScardBase.h"
       
    24 #include    "ScardClsv.h"
       
    25 #include    "ScardComm.h"
       
    26 #include    "ScardConnectionRequirement.h"
       
    27 #include    "WimTrace.h"
       
    28 
       
    29 #ifdef _DEBUG   // for logging
       
    30 #include    "ScardLogs.h"
       
    31 #include    <flogger.h> 
       
    32 #endif
       
    33 
       
    34 // ============================ MEMBER FUNCTIONS ===============================
       
    35 
       
    36 // -----------------------------------------------------------------------------
       
    37 // CScardComm::CScardComm
       
    38 // C++ default constructor can NOT contain any code, that
       
    39 // might leave.
       
    40 // -----------------------------------------------------------------------------
       
    41 //
       
    42 CScardComm::CScardComm( RScard* aScard )
       
    43     : iScard( aScard )
       
    44     {
       
    45     _WIMTRACE(_L("WIM|Scard|CScardComm::CScardComm|Begin"));
       
    46     }
       
    47 
       
    48 // -----------------------------------------------------------------------------
       
    49 // CScardComm::ConstructL
       
    50 // Symbian 2nd phase constructor can leave.
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 void CScardComm::ConstructL(
       
    54     TScardConnectionRequirement& aRequirement,
       
    55     TScardReaderName& aReaderName,
       
    56     TRequestStatus& aStatus,
       
    57     const TInt32 aTimeOut )
       
    58     {
       
    59     _WIMTRACE(_L("WIM|Scard|CScardComm::ConstructL|Begin"));
       
    60     aStatus = KRequestPending;
       
    61     TAny* p[KMaxMessageArguments];
       
    62     p[0] = p[1] = p[2] = p[3] = reinterpret_cast<TAny*>( 0 );
       
    63 
       
    64     p[3] = reinterpret_cast<TAny*>( aTimeOut );
       
    65 
       
    66     TInt mode( 0 );
       
    67     
       
    68     if ( aRequirement.iNewReaders )
       
    69         {
       
    70         mode |= KNewReadersOnly;
       
    71         }
       
    72     if ( aRequirement.iNewCards )
       
    73         {
       
    74         mode |= KNewCardsOnly;
       
    75         }
       
    76 
       
    77     //  Reader requirements
       
    78     if ( aRequirement.iExplicitReader )
       
    79         {
       
    80         mode |= KExplicitReader;
       
    81         aReaderName.Copy( *aRequirement.iExplicitReader );
       
    82         }
       
    83     else if ( aRequirement.iExcludedReader )
       
    84         {
       
    85         mode |= KExcludedReader;
       
    86         aReaderName.Copy( *aRequirement.iExcludedReader );
       
    87         }
       
    88     else
       
    89         {
       
    90         mode |= KAnyReader;
       
    91         aReaderName.Copy( _L( "" ) );
       
    92         }
       
    93     
       
    94     p[1] = static_cast<TAny*>( &aReaderName );
       
    95     
       
    96     //  Card requirements
       
    97     if ( aRequirement.iATRBytes )
       
    98         {
       
    99         mode |= KATRSpesified;
       
   100         p[2] = reinterpret_cast<TAny*>( aRequirement.iATRBytes );
       
   101         }
       
   102     else if ( aRequirement.iAIDBytes )
       
   103         {
       
   104         mode |= KApplicationSpesified;
       
   105         p[2] = reinterpret_cast<TAny*>( aRequirement.iAIDBytes );
       
   106         }
       
   107     else
       
   108         {
       
   109         mode |= KAnyCard;
       
   110         }
       
   111 #ifdef _DEBUG
       
   112     RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, 
       
   113         EFileLoggingModeAppend, _L( "CScardComm::ConstructL mode: 0x%x \n" ), 
       
   114         mode );
       
   115 #endif
       
   116 
       
   117     //  Set the connection mode
       
   118     p[0] = reinterpret_cast<TAny*>( mode );
       
   119     TIpcArgs args( p[0], &aReaderName, p[2], p[3] ); 
       
   120     iScard->SendReceive( EScardServerConnectToReader, args, aStatus );
       
   121     }
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // CScardComm::NewL
       
   125 // Two-phased constructor, asynchronous version.
       
   126 // -----------------------------------------------------------------------------
       
   127 //
       
   128 EXPORT_C CScardComm* CScardComm::NewL(
       
   129     RScard* aScard,
       
   130     TScardConnectionRequirement& aRequirement,
       
   131     TScardReaderName& aReaderName,
       
   132     TRequestStatus& aStatus,
       
   133     const TInt32 aTimeOut )
       
   134     {
       
   135     _WIMTRACE(_L("WIM|Scard|CScardComm::NewL|Begin"));
       
   136     __ASSERT_ALWAYS( aScard, 
       
   137         User::Panic( _L( "Null pointer" ), KScPanicNullPointer ) );
       
   138     __ASSERT_ALWAYS( aTimeOut >= 0, User::Leave( KScErrBadArgument ) );
       
   139     
       
   140     CScardComm* self = new( ELeave ) CScardComm( aScard );
       
   141     
       
   142     CleanupStack::PushL( self );
       
   143     self->ConstructL( aRequirement, aReaderName, aStatus, aTimeOut );
       
   144     CleanupStack::Pop( self );
       
   145 
       
   146     return self;
       
   147     }
       
   148  
       
   149 // Destructor
       
   150 EXPORT_C CScardComm::~CScardComm()
       
   151     {
       
   152     _WIMTRACE(_L("WIM|Scard|CScardComm::~CScardComm|Begin"));
       
   153     if ( iScard )
       
   154         {
       
   155         DisconnectFromReader();
       
   156         }
       
   157     }
       
   158 
       
   159 // -----------------------------------------------------------------------------
       
   160 // CScardComm::TransmitToCard
       
   161 // Transmit data to the card
       
   162 // -----------------------------------------------------------------------------
       
   163 //
       
   164 EXPORT_C void CScardComm::TransmitToCard(
       
   165     const TDesC8& aCommand,
       
   166     TDes8& aResponse,
       
   167     TRequestStatus& aStatus,
       
   168     const TInt32 aTimeOut,
       
   169     const TInt8 aChannel ) const
       
   170     {
       
   171     _WIMTRACE(_L("WIM|Scard|CScardComm::TransmitToCard|Begin"));
       
   172 #ifdef _DEBUG
       
   173     RFileLogger::HexDump( KScardLogDir, KScardLogFileName, 
       
   174         EFileLoggingModeAppend, 
       
   175         _S( "CScardComm::TransmitToCard command APDU:\n" ), 0,
       
   176         aCommand.Ptr(), aCommand.Length() );
       
   177 #endif
       
   178     
       
   179     if ( aTimeOut < 0 ) // Check if timeout value is valid
       
   180         {
       
   181         TRequestStatus* status = &aStatus;
       
   182         User::RequestComplete( status, KErrArgument );
       
   183         return; // Return right away
       
   184         }
       
   185 
       
   186     aStatus = KRequestPending;
       
   187     
       
   188     TIpcArgs args( &aCommand,
       
   189                    &aResponse,
       
   190                    aTimeOut,
       
   191                    aChannel );
       
   192 
       
   193     iScard->SendReceive( EScardServerTransmitToCard, args, aStatus );
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CScardComm::CancelTransmit
       
   198 // Cancel transmitting
       
   199 // -----------------------------------------------------------------------------
       
   200 //
       
   201 EXPORT_C void CScardComm::CancelTransmit() const
       
   202     {
       
   203     _WIMTRACE(_L("WIM|Scard|CScardComm::CancelTransmit|Begin"));
       
   204     TIpcArgs args( TIpcArgs::ENothing );
       
   205     iScard->SendReceive( EScardServerCancelTransmit, args );
       
   206     }
       
   207 
       
   208 // -----------------------------------------------------------------------------
       
   209 // CScardComm::GetATRL
       
   210 // This function fetches the answer-to-reset bytes of the SC currently in the 
       
   211 // card reader. If an error occurs during the operation, the  length of the 
       
   212 // ATR bytes is set to zero. 
       
   213 // -----------------------------------------------------------------------------
       
   214 //
       
   215 
       
   216 EXPORT_C void CScardComm::GetATRL( TScardATR& aATR ) const
       
   217     {
       
   218     _WIMTRACE(_L("WIM|Scard|CScardComm::GetATRL|Begin"));
       
   219 
       
   220     TIpcArgs args( ( TAny* )&aATR );
       
   221     TInt err = iScard->SendReceive( EScardServerGetATR, args );
       
   222 
       
   223     if ( err )
       
   224         {
       
   225         User::Leave( err );
       
   226         }
       
   227     }
       
   228 
       
   229 // -----------------------------------------------------------------------------
       
   230 // CScardComm::GetCapabilitiesL
       
   231 // Get proprietary parameters from the reader handler. 
       
   232 // -----------------------------------------------------------------------------
       
   233 //
       
   234 EXPORT_C void CScardComm::GetCapabilitiesL(
       
   235     const TInt32 aTag,
       
   236     TDes8& aValue,
       
   237     const TInt32 aTimeOut ) const
       
   238     {
       
   239     _WIMTRACE(_L("WIM|Scard|CScardComm::GetCapabilitiesL|Begin"));
       
   240     __ASSERT_ALWAYS( aTimeOut >= 0, User::Leave( KScErrBadArgument ) );
       
   241     TAny* p[KMaxMessageArguments];
       
   242     p[0] = reinterpret_cast<TAny*>( 
       
   243         static_cast<TInt>( ( ( aTag & 0xff00L ) >> 8 ) ) ); //Bits 8-15 from tag
       
   244     p[1] = reinterpret_cast<TAny*>( 
       
   245         static_cast<TInt>( ( aTag & 0x00ffL ) ) );  //First 8 bits from tag
       
   246     p[2] = static_cast<TAny*>( &aValue );
       
   247     p[3] = reinterpret_cast<TAny*>( aTimeOut );
       
   248     
       
   249     TIpcArgs args( p[0], p[1], &aValue, p[3] );
       
   250     
       
   251     TInt err = iScard->SendReceive( EScardServerGetCapabilities, args );
       
   252     
       
   253     if ( err ) // Scard error code may be positive
       
   254         {
       
   255         User::Leave( err );
       
   256         }
       
   257     }
       
   258 
       
   259 // -----------------------------------------------------------------------------
       
   260 // CScardComm::Scard
       
   261 // Return Scard object contained within this object.
       
   262 // -----------------------------------------------------------------------------
       
   263 //
       
   264 EXPORT_C RScard* CScardComm::Scard() const
       
   265     {
       
   266     _WIMTRACE(_L("WIM|Scard|CScardComm::Scard|Begin"));
       
   267     return iScard;
       
   268     }
       
   269 
       
   270 // -----------------------------------------------------------------------------
       
   271 // CScardComm::ManageChannel
       
   272 // Channel management function.
       
   273 // -----------------------------------------------------------------------------
       
   274 //
       
   275 EXPORT_C void CScardComm::ManageChannel(
       
   276     const TScChannelManagement aCommand,
       
   277     const TInt8 aArgument,
       
   278     TDes8& aResponseBuffer,
       
   279     TRequestStatus& aStatus,
       
   280     const TInt32 aTimeOut ) const
       
   281     {
       
   282     _WIMTRACE(_L("WIM|Scard|CScardComm::ManageChannel|Begin"));
       
   283     
       
   284     if ( aTimeOut < 0 ) // Check if timeout value is valid
       
   285         {
       
   286         TRequestStatus* status = &aStatus;
       
   287         User::RequestComplete( status, KErrArgument );
       
   288         return; // Return right away
       
   289         }
       
   290 
       
   291     TAny* p[KMaxMessageArguments];
       
   292     
       
   293     p[0] = p[1] = p[2] = p[3] = reinterpret_cast<TAny*>( 0 );
       
   294 
       
   295     p[0] = reinterpret_cast<TAny*>( aCommand );
       
   296 
       
   297     TIpcArgs args( p[0], p[1], p[2], p[3] );    
       
   298     
       
   299     switch ( aCommand )
       
   300         {
       
   301         case EOpenAnyChannel:
       
   302             {
       
   303 #ifdef _DEBUG
       
   304             RFileLogger::Write( KScardLogDir, KScardLogFileName, 
       
   305                 EFileLoggingModeAppend, 
       
   306                 _L( "CScardComm::ManageChannel -- Open Any channel" ) );
       
   307 #endif
       
   308 
       
   309             args.Set( 1, &aResponseBuffer );
       
   310             args.Set( 2, aTimeOut );
       
   311             break;
       
   312             }
       
   313         
       
   314         case ECloseChannel:
       
   315             {
       
   316 #ifdef _DEBUG
       
   317             RFileLogger::Write( KScardLogDir, KScardLogFileName, 
       
   318                 EFileLoggingModeAppend, 
       
   319                 _L( "CScardComm::ManageChannel -- Close channel" ) );
       
   320 #endif
       
   321 
       
   322             args.Set( 1, aArgument );
       
   323             args.Set( 2, aTimeOut );
       
   324             
       
   325             break;
       
   326             }
       
   327         
       
   328         case EChannelStatus:
       
   329             {
       
   330             args.Set( 1, &aResponseBuffer );
       
   331             break;
       
   332             }
       
   333         
       
   334         default:
       
   335             {
       
   336             User::Panic( _L( "Command not supported" ), 
       
   337                 KScPanicNotSupported );
       
   338             break;
       
   339             }
       
   340         }
       
   341 
       
   342     iScard->SendReceive( EScardServerManageChannel, args, aStatus );
       
   343     }
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // CScardComm::DisconnectFromReader
       
   347 // Close connection
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 void CScardComm::DisconnectFromReader() const
       
   351     {
       
   352     _WIMTRACE(_L("WIM|Scard|CScardComm::DisconnectFromReader|Begin"));
       
   353 #ifdef _DEBUG
       
   354     RFileLogger::Write( KScardLogDir, KScardLogFileName, 
       
   355         EFileLoggingModeAppend, _L( "CScardComm::DisconnectFromReader" ) );
       
   356 #endif
       
   357 
       
   358     TIpcArgs args( TIpcArgs::ENothing );
       
   359     iScard->SendReceive( EScardServerDisconnectFromReader, args );
       
   360     }
       
   361 
       
   362 //  End of File