raumichi Geschrieben 19. Februar 2010 Geschrieben 19. Februar 2010 Hallo, ich verzweifle gerade an der Implementierung einer API in meine JAVA-Anwendung, und hoffe irgendjemand kann mir helfen. Ich will einen Kartenleser ansprechen (Krankenversichertenkarte). Bei dem Kartenleser ist eine API dabei, die drei Funktionen zur Verfügung stellt: CT_init, CT_data und CT_close. Die init Funktion und die Close-Funktion laufen problemlos, nur das Aufrufen der CT_data Funktion will mir nicht gelingen. Definiert sind die Funktionen in der API wie folgt: (siehe auch (http://www.smartcardtools.de/ftp/TeleTrust/MKT_T3.pdf) CT_init ( unsigned short ctn , unsigned short ctn) CT_close ( unsigned short ctn) CT_data (unsigned short ctn, unsigned char *dad, unsigned char *sad, unsigned short lenc, unsigned char *command, unsigned short* lenr, unsigned char *response) Ich habe die DLL mittels JNA eingebunden und folgende Klasse definiert: import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Pointer; public class CtTMKartenleser { public interface IKVKarteLibrary extends Library { IKVKarteLibrary INSTANCE = (IKVKarteLibrary) Native.loadLibrary("ctdeutin" , IKVKarteLibrary.class); int CT_init(char shA, char shB); int CT_close(char shA); int CT_data(char shCtn, Pointer dad, Pointer sad, char shLenc, byte[] sCommand, Pointer lenr, byte[] sResponse); } } So und nun will ich die Funktionen aufrufen. CT_init und CT_close funktioniert: // Logische Terminalnummer final char chCtn = 0x00000001; // Portnummer final char chPn = 0x00000220; lib.CT_init(chCtn, chPn); lib.CT_close(chCtn); nur die CT_data (blöderweise die Wichtigste:) ) // Datenfelder für den Zugriff auf CT_DATA byte btDad = 01; byte btSad = 02; char chLenc = 0x11; short shLenr = 0x256; // cLenr, bDad und bSad sind als POINTER zu übergeben ShortByReference p1 = new ShortByReference(); p1.setValue(shLenr); Pointer pLenr = p1.getPointer(); ByteByReference p2 = new ByteByReference(); p2.setValue(btDad); Pointer pDad = p2.getPointer(); ByteByReference p3 = new ByteByReference(); p3.setValue(btSad); Pointer pSad = p3.getPointer(); // verhindert, dass die VM ab****en kann: Native.setProtected(true); // Befehl byte[] resetICC = {0x20, 0x11, 0x01, 0x01, 0x00}; byte[] readBinary = {0x00, (byte) 0xB0, 0x00, 0x00, 0x00}; byte[] request = { 0x20,0x12, 0x01,0x01,0x01, 0x0a, 0x00}; // Rückgabebereich byte[] rsp = new byte[256]; for (int i = 0; i < rsp.length; i++) { rsp[i] = 0; } int iErg = 0; chLenc = (char)request.length; // Nun sind 4 Befehle an das Kartenterminal abzusetzen: iErg = lib.CT_data(chCtn , pDad, pSad, chLenc, (byte[]) request, pLenr, rsp); Vielen Dank schon mal für eure Hilfe!!! Zitieren
flashpixx Geschrieben 19. Februar 2010 Geschrieben 19. Februar 2010 Definiere "funktioniert nicht". Das ist so keine aussagekräftige Beschreibung des Fehlers Zitieren
raumichi Geschrieben 19. Februar 2010 Autor Geschrieben 19. Februar 2010 ich bekomme aus der Funktion 9-stellige Integerwerte zurück. Ich vermute, dass ich die Pointer nicht richtig an die API übergebe, und daher die Übergabewerte nicht passen. Leider hab ich, trotz stundenlangem rumprobieren, es nie geschafft die Funktion aus JAVA heraus korrekt aufzurufen. Eigentlich sollte als Rückgabewert "0" für Fehlerfrei kommen. Zitieren
flashpixx Geschrieben 19. Februar 2010 Geschrieben 19. Februar 2010 So kann Dir niemand helfen, da niemand einen identischen Entwicklungsstand inkl Hardware vor Ort hat. Versuche das ganze einmal via C/C++ anzusteuern und versuche dort eine korrekte Anbindung zu realisieren, dann siehst Du ggf wo Probleme sind Zitieren
raumichi Geschrieben 22. Februar 2010 Autor Geschrieben 22. Februar 2010 Hallo, mit nem C++ Programm funktioniert der Aufruf so korrekt: int ctn=1; unsigned char ct_dad=1; unsigned char sad=2; unsigned short lenr=256; unsigned char commandcode[11]; unsigned char responsearray[501]; commandcode[0]=0x20; commandcode[1]=0x12; commandcode[2]=0x01; commandcode[3]=0x01; commandcode[4]=0x00; commandcode[5]=0x00; commandcode[6]=0x00; commandcode[7]=0x00; commandcode[8]=0x00; commandcode[9]=0x00; commandcode[10]=0x00; // Request ICC zum CT schicken rc=CT_data(ctn,&ct_dad,&sad,5,&commandcode[0],&lenr,&responsearray[0]); Kann mir das irgendjemand nach JAVA übersetzen? Zitieren
Klotzkopp Geschrieben 22. Februar 2010 Geschrieben 22. Februar 2010 mit nem C++ Programm funktioniert der Aufruf so korrekt:Dann frage ich mich doch, warum dein Java-Programm die Funktion mit ganz anderen Daten aufruft. In C++ übergibst du ein Array von 11 Bytes, gibst aber beim Längenparameter 5 an. Das mag ja noch gehen. Aber in Java übergibst du ein Array von nur 7 Bytes, gibst aber als Länge 17 an. Das kann ja nur in die Hose gehen. Ich korrigiere mich: Du gibst in Java die richtige Länge an. Aber die Daten im Eingabearray sind immer noch unterschiedlich. Zitieren
raumichi Geschrieben 22. Februar 2010 Autor Geschrieben 22. Februar 2010 Hallo, sorry, aber meine JAVA-Code hat sich zwischenzeitlich auch geändert und sieht nun nach langem auspropieren so aus: final char chCtn = 0x00000001; byte btDad = 01; byte btSad = 02; char chLenc = 0x5; short shLenr = 256; // cLenr, bDad und bSad sind als POINTER zu übergeben ShortByReference p1 = new ShortByReference(); p1.setValue(shLenr); Pointer pLenr = p1.getPointer(); ByteByReference p2 = new ByteByReference(); p2.setValue(btDad); Pointer pDad = p2.getPointer(); ByteByReference p3 = new ByteByReference(); p3.setValue(btSad); Pointer pSad = p3.getPointer(); // Befehl byte[] resetICC = {0x20, 0x12, 0x01, 0x01, 0x00,0x00, 0x00, 0x00, 0x00, 0x00 }; byte[] rsp = new byte[501]; for (int i = 0; i < rsp.length; i++) { rsp[i] = 0; } int iErg = 0; chLenc = (char)5; iErg = lib.CT_data(chCtn , pDad, pSad, chLenc, resetICC, pLenr, rsp); System.out.println("Fehlercode von REQUEST: " + iErg); for (int i = 0; i < rsp.length; i++) { rsp[i] = 0; } Als Ergebnis liefert die Funktion "181031168" zurück. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.