A.Vila
A.Vila

Reputation: 1496

SCardTransmit, how to read and write smartcard

I'm working on a printer, trying to read and write a contactless card.

This is the manual of the hardware and software I'm using: manual contactless

The process to ineract with the smart card (read and write in it), if I understood correctly, is:

  1. Establish the Context using SCardEstablishContext()
  2. Connect to the card through the selected reader using SCardConnect()
  3. Talk to the card using SCardTransmit()

Is that correct?

Points 1 and 2 works ok and return 0 (SCARD_S_SUCCESS), but I have problems with SCardTransmit.

Thank you very much!

Upvotes: 5

Views: 6627

Answers (2)

Juan
Juan

Reputation: 830

I know this post is old but I had the same problem with error code 22 on the transmit function. The problem was related to the protocol used.
And actually the simplest is to use the return from the connect function to the card to determine which protocol structure to use with the transmit function.

I am therefore sharing the piece of code which works well and solves the problem of error code 22. Afterwards it remains to use the correct APDU command to obtain the correct result, depending on the card used. The example in the code should allow you to select the AID of a bank card.

hope this can help those who are facing the same error code 22

// Initialization
LONG responceCardFonc = 0;
SCARDCONTEXT contextManager;
LPCSTR readerName = "";
SCARDHANDLE identConnCard;
DWORD m_dwActiveProtocol;
SCARD_IO_REQUEST protocolStruct;
BYTE apduCommand[] = {0x00,0xA4,0x04,0x00,0x07,0xA0,0x00,0x00,0x00,0x03,0x10,0x10};
DWORD nbDataCommand = sizeof(apduCommand);
BYTE dataRecept[256];
DWORD nbDataRecept = sizeof(dataRecept);
QString stringDisplay;

// Determination Name Reader
readerName = "SCM Microsystems Inc. SCR331-DI Smart Card Reader 0";

// Creating a Context
responceCardFonc = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &contextManager);

// If Context Established
if(responceCardFonc==SCARD_S_SUCCESS)
{
  // Card Connection
  responceCardFonc = SCardConnectA(contextManager,readerName,SCARD_SHARE_SHARED,SCARD_PROTOCOL_Tx,&identConnCard,&m_dwActiveProtocol);

  // If Card Connection Successful
  if(responceCardFonc==SCARD_S_SUCCESS)
  {
    // Determining the Protocol Structure to Use
    if(m_dwActiveProtocol==SCARD_PROTOCOL_T0) protocolStruct = *SCARD_PCI_T0;
    if(m_dwActiveProtocol==SCARD_PROTOCOL_T1) protocolStruct = *SCARD_PCI_T1;

    // Transmission to Card
    responceCardFonc = SCardTransmit(identConnCard,&protocolStruct,apduCommand,nbDataCommand,NULL,dataRecept,&nbDataRecept);

    // If Transmission Successful
    if(responceCardFonc==SCARD_S_SUCCESS)
    {
      // Construct String to Display
      for(int i=0;i<nbDataRecept;i++) stringDisplay += QString::number( dataRecept[i], 16 ).toUpper()+((i<nbDataRecept-1)?" ":"");

      // Display String
      qDebug() << stringDisplay;
    }
    // End - If Transmission Successful
    else qDebug() << "Transmission Error - Error Code ["+QString::number(responceCardFonc)+"]";
  }
  // End - If Card Connection Successful
  else qDebug() << "Card Connection Error on "+(QString)readerName+"\nError Code ["+QString::number(responceCardFonc)+"]";
}
// End - If Context Established
else qDebug() << "Context Creation Error"+QString("\n")+"Code Erreur ["+QString::number(responceCardFonc)+"]";

Of course this piece of code is integrated into a project correctly configured with the “winscard” APIs

Upvotes: 1

sudesh kumar
sudesh kumar

Reputation: 45

`enter code here` we  must  check protocol using switch case and transmit like :


switch ( m_dwAP )
    {
    case SCARD_PROTOCOL_T0:
        dwErrorFlags = SCardTransmit(this->m_hCardHandle,
                        SCARD_PCI_T0,
                        rgbIN,
                        bIN,
                        NULL,
                        rgbOUTTra,
                        &uwBufferLen);
        break;
    case SCARD_PROTOCOL_T1:
        dwErrorFlags = SCardTransmit(this->m_hCardHandle,
                        SCARD_PCI_T1,
                        rgbIN,
                        bIN,
                        NULL,
                        rgbOUTTra,
                        &uwBufferLen);
        break;
}
here m_dwAP  is active protocol.

Upvotes: -1

Related Questions