Logo Search packages:      
Sourcecode: pcsc-lite version File versions  Download package

LONG SCardTransmit ( SCARDHANDLE  hCard,
const SCARD_IO_REQUEST pioSendPci,
LPCBYTE  pbSendBuffer,
DWORD  cbSendLength,
SCARD_IO_REQUEST pioRecvPci,
LPBYTE  pbRecvBuffer,
LPDWORD  pcbRecvLength 
)

Sends an APDU to the smart card contained in the reader connected to by SCardConnect().

The card responds from the APDU and stores this response in pbRecvBuffer and it's length in pcbRecvLength. pioSendPci and pioRecvPci are structures containing the following:

 typedef struct {
    DWORD dwProtocol;    // SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1
    DWORD cbPciLength;   // Length of this structure - not used
 } SCARD_IO_REQUEST;
Parameters:
[in]hCardConnection made from SCardConnect().
[in,out]pioSendPciStructure of Protocol Control Information.

[in]pbSendBufferAPDU to send to the card.
[in]cbSendLengthLength of the APDU.
[in,out]pioRecvPciStructure of protocol information.
[out]pbRecvBufferResponse from the card.
[in,out]pcbRecvLengthLength of the response.
Returns:
Error code.
Return values:
SCARD_S_SUCCESSSuccessful (SCARD_S_SUCCESS)
SCARD_E_INSUFFICIENT_BUFFERcbSendLength or cbRecvLength are too big (SCARD_E_INSUFFICIENT_BUFFER)
SCARD_E_INVALID_HANDLEInvalid hCard handle (SCARD_E_INVALID_HANDLE)
SCARD_E_INVALID_PARAMETERpbSendBuffer or pbRecvBuffer or pcbRecvLength or pioSendPci is null (SCARD_E_INVALID_PARAMETER)
SCARD_E_INVALID_VALUEInvalid Protocol, reader name, etc (SCARD_E_INVALID_VALUE)
SCARD_E_NO_SERVICEThe server is not runing (SCARD_E_NO_SERVICE)
SCARD_E_NOT_TRANSACTEDAPDU exchange not successful (SCARD_E_NOT_TRANSACTED)
SCARD_E_PROTO_MISMATCHConnect protocol is different than desired (SCARD_E_PROTO_MISMATCH)
SCARD_E_READER_UNAVAILABLEThe reader has been removed (SCARD_E_READER_UNAVAILABLE)
SCARD_F_COMM_ERRORAn internal communications error has been detected (SCARD_F_COMM_ERROR)
SCARD_W_RESET_CARDThe card has been reset by another application (SCARD_W_RESET_CARD)
SCARD_W_REMOVED_CARDThe card has been removed from the reader (SCARD_W_REMOVED_CARD)
 LONG rv;
 SCARDCONTEXT hContext;
 SCARDHANDLE hCard;
 DWORD dwActiveProtocol, dwSendLength, dwRecvLength;
 SCARD_IO_REQUEST pioRecvPci;
 BYTE pbRecvBuffer[10];
 BYTE pbSendBuffer[] = { 0xC0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00 };
 ...
 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
 rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED,
          SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
 dwSendLength = sizeof(pbSendBuffer);
 dwRecvLength = sizeof(pbRecvBuffer);
 rv = SCardTransmit(hCard, SCARD_PCI_T0, pbSendBuffer, dwSendLength,
          &pioRecvPci, pbRecvBuffer, &dwRecvLength);

Definition at line 2773 of file winscard_clnt.c.

References pubReaderStatesList::cardProtocol, SCARD_IO_REQUEST::cbPciLength, _psContextMap::dwClientID, SCARD_IO_REQUEST::dwProtocol, IFDTransmit(), MAX_BUFFER_SIZE_EXTENDED, MessageReceive(), MessageSend(), MessageSendWithHeader(), _psContextMap::mMutex, PCSCLITE_LOCK_POLL_RATE, pubReaderStatesList::readerState, ReaderContext::readerState, SCARD_ABSENT, SCARD_E_INSUFFICIENT_BUFFER, SCARD_E_INVALID_HANDLE, SCARD_E_INVALID_PARAMETER, SCARD_E_NO_SMARTCARD, SCARD_E_PROTO_MISMATCH, SCARD_E_SHARING_VIOLATION, SCARD_PROTOCOL_ANY, SCARD_PROTOCOL_ANY_OLD, SCARD_PROTOCOL_RAW, SCARD_PROTOCOL_T1, SCARD_S_SUCCESS, SCARD_TRANSMIT, SYS_USleep(), and ReaderContext::version.

{
      LONG rv;
      SCONTEXTMAP * currentContextMap;
      CHANNEL_MAP * pChannelMap;
      struct transmit_struct scTransmitStruct;

      PROFILE_START

      if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
                  pcbRecvLength == NULL || pioSendPci == NULL)
            return SCARD_E_INVALID_PARAMETER;

      CHECK_SAME_PROCESS

      /*
       * Make sure this handle has been opened
       */
      rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
            &pChannelMap);
      if (rv == -1)
      {
            *pcbRecvLength = 0;
            PROFILE_END(SCARD_E_INVALID_HANDLE)
            return SCARD_E_INVALID_HANDLE;
      }

      (void)pthread_mutex_lock(currentContextMap->mMutex);

      /* check the handle is still valid */
      rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
            &pChannelMap);
      if (rv == -1)
            /* the handle is now invalid
             * -> another thread may have called SCardReleaseContext
             * -> so the mMutex has been unlocked */
            return SCARD_E_INVALID_HANDLE;

      if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
            || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
      {
            rv = SCARD_E_INSUFFICIENT_BUFFER;
            goto end;
      }

      /* Retry loop for blocking behaviour */
retry:

      scTransmitStruct.hCard = hCard;
      scTransmitStruct.cbSendLength = cbSendLength;
      scTransmitStruct.pcbRecvLength = *pcbRecvLength;
      scTransmitStruct.ioSendPciProtocol = pioSendPci->dwProtocol;
      scTransmitStruct.ioSendPciLength = pioSendPci->cbPciLength;
      scTransmitStruct.rv = SCARD_S_SUCCESS;

      if (pioRecvPci)
      {
            scTransmitStruct.ioRecvPciProtocol = pioRecvPci->dwProtocol;
            scTransmitStruct.ioRecvPciLength = pioRecvPci->cbPciLength;
      }
      else
      {
            scTransmitStruct.ioRecvPciProtocol = SCARD_PROTOCOL_ANY;
            scTransmitStruct.ioRecvPciLength = sizeof(SCARD_IO_REQUEST);
      }

      rv = MessageSendWithHeader(SCARD_TRANSMIT, currentContextMap->dwClientID,
            sizeof(scTransmitStruct), (void *) &scTransmitStruct);

      if (rv != SCARD_S_SUCCESS)
            goto end;

      /* write the sent buffer */
      rv = MessageSend((void *)pbSendBuffer, cbSendLength,
            currentContextMap->dwClientID);

      if (rv != SCARD_S_SUCCESS)
            goto end;

      /*
       * Read a message from the server
       */
      rv = MessageReceive(&scTransmitStruct, sizeof(scTransmitStruct),
            currentContextMap->dwClientID);

      if (rv != SCARD_S_SUCCESS)
            goto end;

      if (SCARD_S_SUCCESS == scTransmitStruct.rv)
      {
            /* read the received buffer */
            rv = MessageReceive(pbRecvBuffer, scTransmitStruct.pcbRecvLength,
                  currentContextMap->dwClientID);

            if (rv != SCARD_S_SUCCESS)
                  goto end;

            if (pioRecvPci)
            {
                  pioRecvPci->dwProtocol = scTransmitStruct.ioRecvPciProtocol;
                  pioRecvPci->cbPciLength = scTransmitStruct.ioRecvPciLength;
            }
      }

      rv = scTransmitStruct.rv;

      if (sharing_shall_block && (SCARD_E_SHARING_VIOLATION == rv))
      {
            (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
            goto retry;
      }

      *pcbRecvLength = scTransmitStruct.pcbRecvLength;

end:
      (void)pthread_mutex_unlock(currentContextMap->mMutex);

    PROFILE_END(rv)

      return rv;
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index