diff -r 000000000000 -r 164170e6151a wim/Scard/src/ScardComm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wim/Scard/src/ScardComm.cpp Tue Jan 26 15:20:08 2010 +0200 @@ -0,0 +1,362 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Core class for all Smart Card aware applications to use when +* communicating with the card. +* +*/ + + + +// INCLUDE FILES +#include "Scard.h" +#include "ScardBase.h" +#include "ScardClsv.h" +#include "ScardComm.h" +#include "ScardConnectionRequirement.h" +#include "WimTrace.h" + +#ifdef _DEBUG // for logging +#include "ScardLogs.h" +#include +#endif + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CScardComm::CScardComm +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CScardComm::CScardComm( RScard* aScard ) + : iScard( aScard ) + { + _WIMTRACE(_L("WIM|Scard|CScardComm::CScardComm|Begin")); + } + +// ----------------------------------------------------------------------------- +// CScardComm::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CScardComm::ConstructL( + TScardConnectionRequirement& aRequirement, + TScardReaderName& aReaderName, + TRequestStatus& aStatus, + const TInt32 aTimeOut ) + { + _WIMTRACE(_L("WIM|Scard|CScardComm::ConstructL|Begin")); + aStatus = KRequestPending; + TAny* p[KMaxMessageArguments]; + p[0] = p[1] = p[2] = p[3] = reinterpret_cast( 0 ); + + p[3] = reinterpret_cast( aTimeOut ); + + TInt mode( 0 ); + + if ( aRequirement.iNewReaders ) + { + mode |= KNewReadersOnly; + } + if ( aRequirement.iNewCards ) + { + mode |= KNewCardsOnly; + } + + // Reader requirements + if ( aRequirement.iExplicitReader ) + { + mode |= KExplicitReader; + aReaderName.Copy( *aRequirement.iExplicitReader ); + } + else if ( aRequirement.iExcludedReader ) + { + mode |= KExcludedReader; + aReaderName.Copy( *aRequirement.iExcludedReader ); + } + else + { + mode |= KAnyReader; + aReaderName.Copy( _L( "" ) ); + } + + p[1] = static_cast( &aReaderName ); + + // Card requirements + if ( aRequirement.iATRBytes ) + { + mode |= KATRSpesified; + p[2] = reinterpret_cast( aRequirement.iATRBytes ); + } + else if ( aRequirement.iAIDBytes ) + { + mode |= KApplicationSpesified; + p[2] = reinterpret_cast( aRequirement.iAIDBytes ); + } + else + { + mode |= KAnyCard; + } +#ifdef _DEBUG + RFileLogger::WriteFormat( KScardLogDir, KScardLogFileName, + EFileLoggingModeAppend, _L( "CScardComm::ConstructL mode: 0x%x \n" ), + mode ); +#endif + + // Set the connection mode + p[0] = reinterpret_cast( mode ); + TIpcArgs args( p[0], &aReaderName, p[2], p[3] ); + iScard->SendReceive( EScardServerConnectToReader, args, aStatus ); + } + +// ----------------------------------------------------------------------------- +// CScardComm::NewL +// Two-phased constructor, asynchronous version. +// ----------------------------------------------------------------------------- +// +EXPORT_C CScardComm* CScardComm::NewL( + RScard* aScard, + TScardConnectionRequirement& aRequirement, + TScardReaderName& aReaderName, + TRequestStatus& aStatus, + const TInt32 aTimeOut ) + { + _WIMTRACE(_L("WIM|Scard|CScardComm::NewL|Begin")); + __ASSERT_ALWAYS( aScard, + User::Panic( _L( "Null pointer" ), KScPanicNullPointer ) ); + __ASSERT_ALWAYS( aTimeOut >= 0, User::Leave( KScErrBadArgument ) ); + + CScardComm* self = new( ELeave ) CScardComm( aScard ); + + CleanupStack::PushL( self ); + self->ConstructL( aRequirement, aReaderName, aStatus, aTimeOut ); + CleanupStack::Pop( self ); + + return self; + } + +// Destructor +EXPORT_C CScardComm::~CScardComm() + { + _WIMTRACE(_L("WIM|Scard|CScardComm::~CScardComm|Begin")); + if ( iScard ) + { + DisconnectFromReader(); + } + } + +// ----------------------------------------------------------------------------- +// CScardComm::TransmitToCard +// Transmit data to the card +// ----------------------------------------------------------------------------- +// +EXPORT_C void CScardComm::TransmitToCard( + const TDesC8& aCommand, + TDes8& aResponse, + TRequestStatus& aStatus, + const TInt32 aTimeOut, + const TInt8 aChannel ) const + { + _WIMTRACE(_L("WIM|Scard|CScardComm::TransmitToCard|Begin")); +#ifdef _DEBUG + RFileLogger::HexDump( KScardLogDir, KScardLogFileName, + EFileLoggingModeAppend, + _S( "CScardComm::TransmitToCard command APDU:\n" ), 0, + aCommand.Ptr(), aCommand.Length() ); +#endif + + if ( aTimeOut < 0 ) // Check if timeout value is valid + { + TRequestStatus* status = &aStatus; + User::RequestComplete( status, KErrArgument ); + return; // Return right away + } + + aStatus = KRequestPending; + + TIpcArgs args( &aCommand, + &aResponse, + aTimeOut, + aChannel ); + + iScard->SendReceive( EScardServerTransmitToCard, args, aStatus ); + } + +// ----------------------------------------------------------------------------- +// CScardComm::CancelTransmit +// Cancel transmitting +// ----------------------------------------------------------------------------- +// +EXPORT_C void CScardComm::CancelTransmit() const + { + _WIMTRACE(_L("WIM|Scard|CScardComm::CancelTransmit|Begin")); + TIpcArgs args( TIpcArgs::ENothing ); + iScard->SendReceive( EScardServerCancelTransmit, args ); + } + +// ----------------------------------------------------------------------------- +// CScardComm::GetATRL +// This function fetches the answer-to-reset bytes of the SC currently in the +// card reader. If an error occurs during the operation, the length of the +// ATR bytes is set to zero. +// ----------------------------------------------------------------------------- +// + +EXPORT_C void CScardComm::GetATRL( TScardATR& aATR ) const + { + _WIMTRACE(_L("WIM|Scard|CScardComm::GetATRL|Begin")); + + TIpcArgs args( ( TAny* )&aATR ); + TInt err = iScard->SendReceive( EScardServerGetATR, args ); + + if ( err ) + { + User::Leave( err ); + } + } + +// ----------------------------------------------------------------------------- +// CScardComm::GetCapabilitiesL +// Get proprietary parameters from the reader handler. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CScardComm::GetCapabilitiesL( + const TInt32 aTag, + TDes8& aValue, + const TInt32 aTimeOut ) const + { + _WIMTRACE(_L("WIM|Scard|CScardComm::GetCapabilitiesL|Begin")); + __ASSERT_ALWAYS( aTimeOut >= 0, User::Leave( KScErrBadArgument ) ); + TAny* p[KMaxMessageArguments]; + p[0] = reinterpret_cast( + static_cast( ( ( aTag & 0xff00L ) >> 8 ) ) ); //Bits 8-15 from tag + p[1] = reinterpret_cast( + static_cast( ( aTag & 0x00ffL ) ) ); //First 8 bits from tag + p[2] = static_cast( &aValue ); + p[3] = reinterpret_cast( aTimeOut ); + + TIpcArgs args( p[0], p[1], &aValue, p[3] ); + + TInt err = iScard->SendReceive( EScardServerGetCapabilities, args ); + + if ( err ) // Scard error code may be positive + { + User::Leave( err ); + } + } + +// ----------------------------------------------------------------------------- +// CScardComm::Scard +// Return Scard object contained within this object. +// ----------------------------------------------------------------------------- +// +EXPORT_C RScard* CScardComm::Scard() const + { + _WIMTRACE(_L("WIM|Scard|CScardComm::Scard|Begin")); + return iScard; + } + +// ----------------------------------------------------------------------------- +// CScardComm::ManageChannel +// Channel management function. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CScardComm::ManageChannel( + const TScChannelManagement aCommand, + const TInt8 aArgument, + TDes8& aResponseBuffer, + TRequestStatus& aStatus, + const TInt32 aTimeOut ) const + { + _WIMTRACE(_L("WIM|Scard|CScardComm::ManageChannel|Begin")); + + if ( aTimeOut < 0 ) // Check if timeout value is valid + { + TRequestStatus* status = &aStatus; + User::RequestComplete( status, KErrArgument ); + return; // Return right away + } + + TAny* p[KMaxMessageArguments]; + + p[0] = p[1] = p[2] = p[3] = reinterpret_cast( 0 ); + + p[0] = reinterpret_cast( aCommand ); + + TIpcArgs args( p[0], p[1], p[2], p[3] ); + + switch ( aCommand ) + { + case EOpenAnyChannel: + { +#ifdef _DEBUG + RFileLogger::Write( KScardLogDir, KScardLogFileName, + EFileLoggingModeAppend, + _L( "CScardComm::ManageChannel -- Open Any channel" ) ); +#endif + + args.Set( 1, &aResponseBuffer ); + args.Set( 2, aTimeOut ); + break; + } + + case ECloseChannel: + { +#ifdef _DEBUG + RFileLogger::Write( KScardLogDir, KScardLogFileName, + EFileLoggingModeAppend, + _L( "CScardComm::ManageChannel -- Close channel" ) ); +#endif + + args.Set( 1, aArgument ); + args.Set( 2, aTimeOut ); + + break; + } + + case EChannelStatus: + { + args.Set( 1, &aResponseBuffer ); + break; + } + + default: + { + User::Panic( _L( "Command not supported" ), + KScPanicNotSupported ); + break; + } + } + + iScard->SendReceive( EScardServerManageChannel, args, aStatus ); + } + +// ----------------------------------------------------------------------------- +// CScardComm::DisconnectFromReader +// Close connection +// ----------------------------------------------------------------------------- +// +void CScardComm::DisconnectFromReader() const + { + _WIMTRACE(_L("WIM|Scard|CScardComm::DisconnectFromReader|Begin")); +#ifdef _DEBUG + RFileLogger::Write( KScardLogDir, KScardLogFileName, + EFileLoggingModeAppend, _L( "CScardComm::DisconnectFromReader" ) ); +#endif + + TIpcArgs args( TIpcArgs::ENothing ); + iScard->SendReceive( EScardServerDisconnectFromReader, args ); + } + +// End of File