#include <winscard.h>   /* PC/SC Prototypen */
#include <stdio.h>

int main(void)
{
    SCARDCONTEXT Context;                /* Kontext zum Ressource Manager */
    SCARDHANDLE  CardHandle;    	 /* Handle auf die Chipkarte */
    DWORD        Protocol;      	 /* verwendetes Übertragungsprotokoll */
    LONG         result;        	 /* Variable für Return-Codes */   
    DWORD        dwReaders;     	 /* Anzahl der verfügbaren Terminals */
    LPSTR        mszReaders;    	 /* String-Liste der verfügbaren Terminals */
    int          i,p,iList[20],reader;	 /* Hilfsvariablen */
    SCARD_READERSTATE_A readerState[1];  /* Status des Terminals */
    DWORD responseLength;                /* Antwortlänge */
    unsigned char response[100];	 /* Puffer für Antwort-APDU */
    unsigned short int trailer;          /* Antwort Trailer */	

			 /* CLA  INS   P1   P2   Lc     Data */ 
    unsigned char APDU[] = {0xA0,0xA4,0x00,0x00,0x02,0x7F,0x10}; /* GSM-Kommando SELECT 7F10 */		

    /* Verbindung zum PC/SC Ressource Manager aufbauen */
    result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &Context);	

    if (result==SCARD_S_SUCCESS)
    {
	    printf("Verbindung zum Ressource Manager konnte erfolgreich aufgebaut werden.\n");

	    /* Liste aller über den Ressource Manager ereichbaren Terminals ermitteln */		
	    SCardListReaders(Context, NULL, NULL, &dwReaders);
	    mszReaders = (LPSTR)malloc(sizeof(char)*dwReaders);
	    SCardListReaders(Context, NULL, mszReaders, &dwReaders);

	    p = 0;		
	    for (i=0;i<dwReaders-1;i++)
	    {
		    p++; 
		    iList[p] = i;		 
		    printf("Terminal %d: %s\n",p, &mszReaders[i]);
		    while (mszReaders[++i] != 0);
	    }
		
	    do 
	    {
		printf("Geben Sie bitte die gewünschte Terminal-Nummer ein: ");
		scanf("%d",&reader);
	    }
	    while ((reader>p) || (reader <=0));

	    readerState[0].szReader = &mszReaders[iList[reader]];
	    readerState[0].dwCurrentState = SCARD_STATE_EMPTY;

	    /* wartet solange bis Karte eingelegt wird */
	    printf("Chipkarte einlegen ... \n");
	    SCardGetStatusChange(Context, INFINITE, readerState, 1);

	    /* mit dem gewünschten Terminal verbinden */		
	    result = SCardConnect(Context,
				  &mszReaders[iList[reader]],
				  SCARD_SHARE_SHARED,
				  SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
				  &CardHandle, 
				  &Protocol);

	    if (result == SCARD_S_SUCCESS)
	    {
		printf("Karten-Verbindung steht ... \n");

		/* APDU an die Karte schicken */					
		responseLength = sizeof(response);
	        result = SCardTransmit(CardHandle, SCARD_PCI_T0, APDU, sizeof(APDU), NULL, response, &responseLength);	

		if (result==SCARD_S_SUCCESS)		
		{
		   printf("Antwort Trailer SW1=%.2xh SW2=%.2xh\n",response[0], response[1]);	

		   if ( (response[0]==0x90) || (response[0]==0x97))
		   {
		      /* APDU konnte ausgeführt werden - Auswerten der Antwort-APDU 
			    .....
		      */
		   }

 		   SCardDisconnect(CardHandle, SCARD_EJECT_CARD);  /* Verbindung trennen */					
		}
		else
		    printf("Transmit der APDU fehlgeschlagen\n");		
	    }										
	    else
		printf("Verbindung fehlgeschlagen\n");

	    SCardReleaseContext(Context);	/* Kontext zum Ressource Manager wieder freigeben */		
    }
    else
	    printf("Verbindungsaufbau zum Ressource Manager fehlgeschlagen\n" \
		   "!!! möglicherweise /usr/local/pcscd nicht gestartet !!!\n");	
}
