Chipkarte über LPT
LeKuchen
- programmiertechnik
Hallo,
ich habe hier ein Chipkartenlesegerät über LPT angeschlossen. Weiss zufällig jemand, wie ich an die Daten auf der Chipkarte komme?
Muss ich einen LPT-Port abhorchen? Hat jemand Links?
Gruß,
LeKuchen
P.S.: Ja, sorry ist nicht direkt HTML, aber hier sind ja soviele Cracks...
Sup!
ich habe hier ein Chipkartenlesegerät über LPT angeschlossen. Weiss zufällig jemand, wie ich an die Daten auf der Chipkarte komme?
Das kommt darauf an. Was für eine Chipkarte. Was für ein Leser. Was für ein Protokoll.
Muss ich einen LPT-Port abhorchen? Hat jemand Links?
Das kommt auf's OS an.
Gruesse,
Bio
Hallo,
Das kommt darauf an. Was für eine Chipkarte. Was für ein Leser. Was für ein Protokoll.
Nein, kommt nicht unbedingt drauf an. (Bin übrigens von LPT auf COM gegangen.)
Ok, grobe Einschränkung der Chipkarte: Eine kontaktbehaftete Speicherkarte. (Telefonkarte, Gesundheitskarte, Bankkarte etc. Andere müßten aber theoretisch auch gehen. Eigentlich müssten alle Speicherkarten relativ gleich zu lesen sein. Einziger Unterschied: in welchem Bereich des Buffers welche Werte stehen.)
BTW: Leser und Karten sind genormt.
Das kommt auf's OS an.
Naja...
FYI, habe da was ausgegraben. Etwas länger, aber da Du mir ja sonst bestimmt nicht glaubst....Kannst ja mal ausprobieren. ;o)
Gruß, LeKuchen
PS: Ab hier nur für Interessierte....
#include <windows.h>
#define DLLExport __declspec( dllexport ) WINAPI
HANDLE hCom; unsigned char InBuff[255]; char SendSeqNr;
void ProtError (LPSTR Meld) { char szBuff[255]; wsprintf(szBuff,"%s, Error %u\n",Meld,GetLastError()); MessageBox(NULL,szBuff,"Cardreader",MB_ICONHAND); }
int OpenComm (void) { DCB dcb; COMMTIMEOUTS CTO; DWORD dwError; BOOL fSuccess;
hCom = CreateFile("COM2", GENERIC_READ | GENERIC_WRITE, 0, /* comm devices must be opened w/exclusive-access / NULL, / no security attrs / OPEN_EXISTING, / comm devices must use OPEN_EXISTING / 0, / not overlapped I/O / NULL / hTemplate must be NULL for comm devices */ );
if (hCom == INVALID_HANDLE_VALUE) { dwError = GetLastError(); /* handle error */ return(0); }
/* * Omit the call to SetupComm to use the default queue sizes. * Get the current configuration. */
fSuccess = GetCommState(hCom, &dcb);
if (!fSuccess) { /* Handle the error. */ return(0); }
/* Fill in the DCB: baud=9600, 8 data bits, no parity, 1 stop bit. */
dcb.BaudRate = CBR_9600; dcb.ByteSize = 8; dcb.Parity = EVENPARITY; dcb.StopBits = ONESTOPBIT; dcb.fNull = FALSE; dcb.fRtsControl=RTS_CONTROL_DISABLE;
fSuccess = SetCommState(hCom, &dcb); if (!fSuccess) { /* Handle the error. / return(0); } CTO.ReadIntervalTimeout=MAXDWORD; CTO.ReadTotalTimeoutMultiplier=0; CTO.ReadTotalTimeoutConstant=0; CTO.WriteTotalTimeoutMultiplier=0; CTO.WriteTotalTimeoutConstant=0; fSuccess = SetCommTimeouts(hCom, &CTO); if (!fSuccess) { / Handle the error. */ return(0); }
return(1); }
int SendRec (unsigned char * SendStr , int len) { int chksum=0; unsigned char *RdBuff=InBuff; int i, RestToRead, TotalRead=0; DWORD nBytesRead, nBytesToWrite, nBytesWritten;
for (i=0;i<len;i++) { chksum^=(int)(*(SendStr+i)); } *(SendStr+len)=(unsigned char)chksum; nBytesToWrite=len+1; if (WriteFile(hCom,(void *)SendStr,nBytesToWrite,&nBytesWritten,NULL)==0) { ProtError("Send in Sendrec"); return(0); } RestToRead=4; while (RestToRead>0) { if (ReadFile(hCom,(void )RdBuff,RestToRead,&nBytesRead,NULL)==0) { ProtError("Rec2 in Sendrec"); return(0); } RdBuff+=nBytesRead; TotalRead+=nBytesRead; RestToRead-=nBytesRead; } RestToRead=(InBuff+2)-TotalRead+4; while (RestToRead>0) { if (ReadFile(hCom,(void *)RdBuff,RestToRead,&nBytesRead,NULL)==0) { ProtError("Rec2 in Sendrec"); return(0); } RdBuff+=nBytesRead; RestToRead-=nBytesRead; } return(1); }
void ReSynch (void) { unsigned char OutBuff[255];
OutBuff[0]=0x12; OutBuff[1]=0xC0; OutBuff[2]=0x0; SendSeqNr=0; if (SendRec(OutBuff,3)) { if ((InBuff[0]==0x21)&&(InBuff[1]==0xE0)&&(InBuff[2]==0)) return; } ProtError("Resync gescheitert"); }
int CardCtrlComm (unsigned char *CtrlComm, int clclen, unsigned char *SendStr, int strlen) { int i; unsigned char SendBuff[255], *sd=&SendBuff[0], *lb=&SendBuff[2];
*(sd++)=0x12; *(sd++)=SendSeqNr; sd++; *(sd++)=0x20; *lb=1; for (i=0;i<clclen;i++) { *(sd++)=CtrlComm[i]; (*lb)++; } if (strlen) { *(sd++)=strlen; (*lb)++; for (i=0;i<strlen;i++) { *(sd++)=SendStr[i]; (*lb)++; } } if (!SendRec(SendBuff,SendBuff[2]+3)) return(0); if ((InBuff[0]!=0x21)&&(InBuff[1]!=SendSeqNr)) { ProtError("Req- ICC Fehler"); return(0); }
if (SendSeqNr==0) SendSeqNr=64; else SendSeqNr=0; return(1); }
int CardAnwComm (unsigned char *AnwComm, int anwlen, unsigned char *SendStr, int strlen, int *rlen) { int i; unsigned char SendBuff[255], *sd=&SendBuff[0], *lb=&SendBuff[2];
*(sd++)=2; *(sd++)=SendSeqNr; sd++; *(sd++)=0; *lb=1; for (i=0;i<anwlen;i++) { *(sd++)=AnwComm[i]; (*lb)++; } if (strlen) { *(sd++)=strlen; (*lb)++; for (i=0;i<strlen;i++) { *(sd++)=SendStr[i]; (*lb)++; } } if (!SendRec(SendBuff,SendBuff[2]+3)) return(0); if ((InBuff[0]!=0x20)&&(InBuff[1]!=SendSeqNr)) { ProtError("Req- ANW Fehler"); return(0); }
if (SendSeqNr==0) SendSeqNr=64; else SendSeqNr=0; rlen=(InBuff+2); if (*AnwComm==0xB0) (*rlen)-=3; return(1); }
int DLLExport ReadCard (unsigned char *Buffer) { unsigned char S1[5], S2[10], *Resp; int i, rlen;
ReSynch(); S1[0]=0x12; S1[1]=1; S1[2]=0; S2[0]=1; if (!CardCtrlComm(S1,3,S2,1)) return(0); Resp=InBuff+3; if ((Resp[0]==0x62)&&(Resp[1]==0)) { MessageBox(NULL,"keine Karte eingelegt !","Cardreader",MB_ICONHAND); return(0); } if ((Resp[0]!=0x90)&&(Resp[1]!=0)) { MessageBox(NULL,"noch mal versuchen !","Cardreader",MB_ICONHAND); return(0); } S1[0]=0xA4; S1[1]=4; S1[2]=0; S2[0]=0xD2; S2[1]=0x76; S2[2]=0; S2[3]=0; S2[4]=1; S2[5]=1; if (!CardAnwComm(S1,3,S2,6,&rlen)) return(0); Resp=InBuff+3; if ((Resp[0]==0x6A)&&(Resp[1]==0x82)) { ProtError("Appl. not found or Data incorrect"); return(0); } if ((Resp[0]!=0x90)&&(Resp[1]!=0)) { ProtError("Select incorrect !"); return(0); } S1[0]=0xB0; S1[1]=0; S1[2]=0; S1[3]=0; if (!CardAnwComm(S1,4,S2,0,&rlen)) return(0); // Resp=InBuff+3; Resp=InBuff+rlen+4; if ((Resp[0]==0x62)&&(Resp[1]==0x82)) { // end of data before ... OKAY ! } else if ((Resp[0]==0x65)&&(Resp[1]==1)) { ProtError("Memory corrupted !"); return(0); } else if ((Resp[0]==0x6B)&&(Resp[0]==1)) { ProtError("Wrong offset !"); return(0); } else if ((Resp[0]!=0x90)&&(Resp[1]!=0)) { ProtError("Read false response"); return(0); } if (rlen>256) rlen=256; for (i=0; i<rlen; i++) { switch(InBuff[i+3]) { case 0x8E: Buffer[i]=196; break; case 0x99: Buffer[i]=214; break; case 0x9A: Buffer[i]=220; break; case 0x84: Buffer[i]=228; break; case 0x94: Buffer[i]=246; break; case 0x81: Buffer[i]=252; break; case 0x7E: Buffer[i]=223; break; default : Buffer[i]=InBuff[i+3]; } } return(rlen); }
BOOL WINAPI DllEntryPoint( HINSTANCE hinstDLL, // handle to DLL module DWORD fdwReason, // reason for calling function LPVOID lpReserved ) // reserved { // Perform actions based on the reason for calling. switch( fdwReason ) { case DLL_PROCESS_ATTACH: // Initialize once for each new process. // Return FALSE to fail DLL load. break;
case DLL_THREAD_ATTACH: // Do thread-specific initialization. break;
case DLL_THREAD_DETACH: // Do thread-specific cleanup. break;
case DLL_PROCESS_DETACH: // Perform any necessary cleanup. break; } return TRUE; // Successful DLL_PROCESS_ATTACH. }
Moin,
Nein, kommt nicht unbedingt drauf an. (Bin übrigens von LPT auf COM gegangen.)
Doch.
Ok, grobe Einschränkung der Chipkarte: Eine kontaktbehaftete Speicherkarte. (Telefonkarte, Gesundheitskarte, Bankkarte etc. Andere müßten aber theoretisch auch gehen. Eigentlich müssten alle Speicherkarten relativ gleich zu lesen sein. Einziger Unterschied: in welchem Bereich des Buffers welche Werte stehen.)
Nein, selbst für Speicherkarten gibt es mindestens 3 Protokolle: I²C, 2-Draht, 3-Draht.
BTW: Leser und Karten sind genormt.
Nein. Ja, aber das bringt dir nichts..
Chipkartenleser kann natürlich jeder Hersteller basteln wie er will. Es gibt da zwar eine Hand voll Interfaces aus denen man sich eins aussuchen kann wenn man bereits existierende Software nutzen will, aber wenn man als Hersteller nicht unbedingt Wert darauf legt dass man seine Geräte auch verkauft kriegt kann man sich natürlich auch ein tolles Protokoll ausdenken welches auf Versen aus dem 2. Buch Mose basiert.
Was Chipkarten angibt: Ja, da gibt es natürlich ISO-7816 (für Prozessorkarten), aber auch das definiert mehrere Protokolle und hat diverse Erweiterungen.
Hallo,
Nein, selbst für Speicherkarten gibt es mindestens 3 Protokolle: I²C, 2-Draht, 3-Draht.
Du redest hier von Datenbussen und nicht von Protokollen. Und du zählst Apfelsorten und Birnen auf, da z.B. I²C ein 2-Draht-Bus ist.
BTW: Leser und Karten sind genormt.
Nein. Ja, aber das bringt dir nichts..
Ja was denn jetzt? Ja oder Nein?
Chipkartenleser kann natürlich jeder Hersteller basteln wie er will.
Natürlich kann jeder Hersteller das. Aber es gibt Zertifizierungsstellen und es gibt Quasi-Standards.
Was Chipkarten angibt: Ja, da gibt es natürlich ISO-7816 (für Prozessorkarten),
Negativ. Erstens sprach ich ja dann wohl von Speicherkarten und nicht von Prozessorkarten. Zweitens: Die sind in ISO-7816 unter 1-3 auch berücksichtigt. Drittens: Für Speicherkarten ist es nicht so schwammig wie für Prozessorkarten.
Gruß,
LeKuchen
Hallo Henryk,
... kann man sich natürlich auch ein tolles Protokoll ausdenken welches auf Versen aus dem 2. Buch Mose basiert.
Ausgerechnet "Exodus", genau der passende Titel für ein Leseprotokoll. *g*
Freundliche Grüsse,
Vinzenz
Sup!
Das kommt darauf an. Was für eine Chipkarte. Was für ein Leser. Was für ein Protokoll.
Nein, kommt nicht unbedingt drauf an. (Bin übrigens von LPT auf COM gegangen.)
Ach, Du bist also mal eben kurz von LPT auf COM "gegangen". Na dann.
Da kannst Du aber auch noch 1001 Problem bekommen, wenn's mit der Baudrate, Xon/Xoff, Stop-Bits etc. nicht klappt.
Aber viel Glück.
Gruesse,
Bio