#include #include #include #include #include #include #include #include #include #include #include "scard_common.h" #define APDUBufSize 65535 #define ReaderName "Athena ASE IIIe 00 00" int sock; SCARDHANDLE hCard; char *szReaderName; SCARDCONTEXT hContext; DWORD dwActiveProtocol; int PrintByteArray ( BYTE *arrBytes, unsigned int nSize ) { int i; for (i=0; i < nSize; i++) { printf ("%X ", arrBytes[i]); } printf ("\n"); } void PrintUsage () { printf ("SCardClient []\n"); printf ("reader name defaults to: %s\n", ReaderName); } int SendMsg ( MsgType type, void *msg, unsigned int nLength ) { LONG rv; SCRMsgHeader mhHeader; mhHeader.type = type; mhHeader.nLength = nLength; rv = write ( sock, &mhHeader, sizeof (mhHeader) ); if (rv < 0) { /* Error */ printf ("write header error\n"); close (sock); return (16); } rv = write ( sock, msg, nLength ); if (rv < 0) { /* Error */ printf ("write error\n"); close (sock); return (16); } return (0); } int WaitForCardInsert () { long rv; SCARD_READERSTATE_A rgReaderStates[1]; rgReaderStates[0].szReader = szReaderName; rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE; rv = SCardGetStatusChange ( hContext, INFINITE, rgReaderStates, 1 ); if (rv != SCARD_S_SUCCESS) { printf ("SCardGetStatusChange Error (%d)\n", rv); } printf ("Reader state: 0x%04X\n", rgReaderStates[0].dwEventState); while (!(rgReaderStates[0].dwEventState & SCARD_STATE_PRESENT)) { /* No card */ printf ("Waiting for card!\n"); rgReaderStates[0].dwCurrentState = rgReaderStates[0].dwEventState; rv = SCardGetStatusChange ( hContext, INFINITE, rgReaderStates, 1 ); if (rv != SCARD_S_SUCCESS) { printf ("SCardGetStatusChange Error (%d)\n", rv); } } rv = SCardConnect ( hContext, szReaderName, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol ); if (rv != SCARD_S_SUCCESS) { printf ("SCardConnect Error (%d)\n", rv); exit (1); } else { printf ("!hCard=%x!\n", hCard); } SendMsg ( SCard_ATR, rgReaderStates[0].rgbAtr, rgReaderStates[0].cbAtr ); printf ("Card inserted!\nATR="); } int main ( int argc, char *argv[] ) { struct sockaddr_in servaddr; SCRMsgHeader mhHeader; LONG rv; SCARD_READERSTATE_A rgReaderStates[1]; DWORD dwSendLength; DWORD dwRecvLength; SCARD_IO_REQUEST pioRecvPci; BYTE pbRecvBuffer[APDUBufSize]; BYTE pbSendBuffer[APDUBufSize]; if (argc == 4) { szReaderName = argv[3]; } else { szReaderName = (char *) malloc (strlen (ReaderName)); strncpy ( szReaderName, ReaderName, strlen (ReaderName) ); if (argc != 3) { PrintUsage(); exit (4); } } sock = socket ( AF_INET, SOCK_STREAM, 0 ); if (sock < 0) { // Error printf ("Error opening socket!\n"); } memset (&servaddr, 0, sizeof (struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr (argv[1]); servaddr.sin_port = htons (atoi(argv[2])); if ( connect ( sock, (struct sockaddr *)&servaddr, sizeof(servaddr) ) < 0 ) { // Error printf ("Could not connect\n"); return (5); } printf ("Connected (sizeof Header=%d)!\n", sizeof (mhHeader)); rv = SCardEstablishContext ( SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext ); if (rv != SCARD_S_SUCCESS) { printf ("SCardEstablishContext error (%d)\n", rv); } rgReaderStates[0].szReader = szReaderName; rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE; rv = SCardGetStatusChange ( hContext, INFINITE, rgReaderStates, 1 ); if (rv != SCARD_S_SUCCESS) { printf ("SCardGetStatusChange Error (%d)\n", rv); } printf ("Reader state: 0x%04X\n", rgReaderStates[0].dwEventState); while (!(rgReaderStates[0].dwEventState & SCARD_STATE_PRESENT)) { /* No card */ printf ("Waiting for card!\n"); rgReaderStates[0].dwCurrentState = rgReaderStates[0].dwEventState; rv = SCardGetStatusChange ( hContext, INFINITE, rgReaderStates, 1 ); if (rv != SCARD_S_SUCCESS) { printf ("SCardGetStatusChange Error (%d)\n", rv); } } printf ("Card inserted!\nATR="); PrintByteArray (rgReaderStates[0].rgbAtr, rgReaderStates[0].cbAtr); SendMsg ( SCard_ATR, rgReaderStates[0].rgbAtr, rgReaderStates[0].cbAtr ); rv = SCardConnect ( hContext, szReaderName, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol ); if (rv != SCARD_S_SUCCESS) { printf ("SCardConnect Error (%d)\n", rv); exit (1); } else { printf ("!hCard=%x!\n", hCard); } do { rv = read ( sock, &mhHeader, sizeof (mhHeader) ); if (rv < 0) { /* Error */ printf ("header read error\n"); return (8); } printf ("Header: type=%d, nLength=%d", mhHeader.type, mhHeader.nLength); switch (mhHeader.type) { case SCard_APDU: rv = read ( sock, pbSendBuffer, mhHeader.nLength ); if (rv < 0) { /* Error */ printf ("read error\n"); close (sock); return (8); } printf ("recv APDU: "); PrintByteArray (pbSendBuffer, mhHeader.nLength); /* Transmit recieved APDU */ dwSendLength = mhHeader.nLength; dwRecvLength = sizeof(pbRecvBuffer); rv = SCardTransmit ( hCard, SCARD_PCI_T0, pbSendBuffer, dwSendLength, &pioRecvPci, pbRecvBuffer, &dwRecvLength ); if (rv == SCARD_S_SUCCESS) { mhHeader.nLength = dwRecvLength; printf ("send APDU: "); PrintByteArray (pbRecvBuffer, mhHeader.nLength); SendMsg ( SCard_APDU, pbRecvBuffer, dwRecvLength ); } else { if (rv == SCARD_W_REMOVED_CARD) { // Card removed SendMsg ( SCard_Remove, NULL, 0 ); WaitForCardInsert (); } else { SendMsg ( SCard_Error, &rv, sizeof (LONG) ); } } break; default: printf ("Default\n"); } } while (rv >= 0); dwSendLength = sizeof(pbSendBuffer); dwRecvLength = sizeof(pbRecvBuffer); rv = SCardTransmit ( hCard, SCARD_PCI_T0, pbSendBuffer, dwSendLength, &pioRecvPci, pbRecvBuffer, &dwRecvLength ); if (rv != SCARD_S_SUCCESS) { printf ("SCardTransmit Error (%d)\n", rv); exit (2); } PrintByteArray (pbRecvBuffer, sizeof (pbRecvBuffer)); return (0); }