Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi CT - Api / Chipkarten (https://www.delphipraxis.net/10624-ct-api-chipkarten.html)

skullcrusher 22. Okt 2003 12:47


CT - Api / Chipkarten
 
Hallo Leute,

ich sitze hier an einem Delphi Projekt und komme einfach nicht so recht
weiter.
Ich muss die Daten einer Chipkarte auslesen ( Krankenkassenkarte )
Eine Verbindung zum Cardreader stelle ich über die bekannte
CT-Api Schnittstelle her.
Die CT-Api dll habe ich eingebunden und über eine import unit die
berühmten Funktionen CT_init, CT_data und CT_close nach
Delphi geholt.
Das alles klappt auch ohne Probleme, daher gehe ich davon aus, das
ich bei der Definition der Funktionen keine Fehler gemacht habe.
Das initalisieren über CT_init und der Close über CT_close funktionieren
auch ohne Probleme.
Nur mit dem CT_data Befehl tue ich mir schwer.
Sobald ich den meiner Meinung nach richtigen Befehl starte bekomme ich
regelmäßig eine Access Violation .
Ich gehe davon aus, daß der Fehler in der Definition des commands liegt.
Laut Beschreibung wird hier ein Zeiger ( Pointer ) auf eine Adresse mit
dem command verlangt. Die Variable soll laut Beschreibung von der Form "byte"
sein.
Also habe ich ein Array of Byte definiert .
Darin dann die einzelnen Hex Angaben ( in der Form $00 ) abgelegt .
In der Doku ist leider nur ein VB Beispiel. Dort wird in der command Sektion
einfach ein Verweis auf das erste Element des Byte Arrays gesetzt.
Also in der Command Sektion einfach command [0] angegeben.
Das funktioniert aber offensichtlich nicht.
Dann versuchte ich, einen Pointer auf das Byte Array zu setzen und diesen anzugeben.
Auch das wurde mit gleicher Fehlermeldung quittiert.
Lange Rede, kurzer Unsinn:
Weiss jemand wie man einen command für die Funktion CT_data richtig angibt ?
Ich bin in Pointersachen leider ziemlich unerfahren.

Bin für jeden Hinweis dankbar,

Bis dann,

Stephan

PS: Wer bis hierhin gelesen hat, bekommt eine öfffentlich Belobigung !
Ich verspreche meine weiteren Beiträge hier werden kürzer !!! :mrgreen:

Leuselator 22. Okt 2003 13:00

Re: CT - Api / Chipkarten
 
poste mal 'n Stück Code - macht es leichter Käfer zu suchen, auch wenn ich Dir wahrscheinlich nicht helfen kann, so doch für Andere
Gruß

skullcrusher 22. Okt 2003 13:07

Re: CT - Api / Chipkarten
 
Hallo Leuselator !

Hm, dachte ich mir ja, Problem ist nur, das ich im Moment den Code zu Hause
habe und hier in der Mittagspause auf der Arbeit sitze.
Schiebe heute abend die Codeparts nach.
Vielleicht fällt Dir ja was dazu ein.

Bis dann,

Stephan

Wormid 22. Okt 2003 14:44

Re: CT - Api / Chipkarten
 
Ich riskiere hier jetzt einfach mal nen Blindschuss... ich habe kein CardTerminal und deshalb auch keine ct-api... Und da das SDK kostenpflichtig zu sein scheint, ist es irgendwie auch nicht so einfach, nähere Informationen zu bekommen.

Das was ich jetzt hier mal testweise zusammengefummelt habe, fusst alles auf Informationen aus diesem Dokument.

Delphi-Quellcode:
// Ich vermute, die Funktionen müssten so oder so ähnlich deklariert sein bzw. werden
function CT_Init(const ctn, pn: Word): ShortInt;
function CT_Data(const ctn: Word; var dad, sad: Byte; const lenc: Word; command: Pointer; var lenr: Word; response: Pointer): ShortInt;
function CT_Close(const ctn: Word): ShortInt;

procedure TestCT;
const OK = 0; // Fehlercodes stehen noch mehr im Dokument
var ctn, lenr: Word;
    dad, sad: Byte;
    command: Array of Byte;
    response: Array[0..1000] of Byte;
    Res: ShortInt;
begin
  ctn := 1;
  // Terminal 1 an Comport 2...
  if CT_Init(ctn, 2) = OK then
  begin
    sad := 2; // Source = Host
    dad := 1; // Destination = Terminal
    lenr := SizeOf(response);
    command[0] := $20; // Commandobytes
    command[1] := $12;
    {...usw...}
    Res := CT_Data(ctn, dad, sad, SizeOf(command), @command, lenr, @response);

    CT_Close(ctn);
  end;
end;
Wie gesagt, ist ein "kalt" geschriebenes Programm, da ich es nicht testen kann.
Ich hoffe, das das eher hilfreich als verwirrend ist - mich würde dann am Ende auch mal interessieren, wie weit ich denn nun daneben lag. :mrgreen:

Gruß

Wormid

skullcrusher 22. Okt 2003 22:07

Re: CT - Api / Chipkarten
 
Hallo Wormid,


danke für die rasche und ausführliche Hilfe !
Leider hat es nicht funktioniert.
Wenn ich bei CT_data mein commando[0] durch Dein @commando ersetze
funktioniert zwar die Compilierung aber der Fehler bleibt der gleiche:
"EAccessViolation bei Adresse 10016D9 in Modul CTORG32.DLL"
(Die Dll ist die CT-Api)
Habe ich eine Chance irgendwie zu ermitteln welche Stelle genau den Fehler
verursacht ? In einer Dll wohl weniger oder ?

Hier mein Code mit dem ich es versuche:

************************************************** ********************
procedure TForm1.Button3Click(Sender: TObject);
var
daten:kdaten;
rueckgabe:word;
commando:array of byte;
speicher:array of byte;

begin
// Select file legt die zu empfangende Datensection fest !
setlength(speicher,2);
setlength(commando,8);
commando[0]:=$00;
commando[1]:=$04;
commando[2]:=$00;
commando[3]:=$88;
commando[4]:=$02;
commando[5]:=$3F;
commando[6]:=$00;
rueckgabe:=CT_data(1,02,01,Sizeof(commando),@comma ndo,2,@speicher);
showmessage(inttostr(rueckgabe));
end;
************************************************** *******************

Wie gesagt, davor funktioniert der CT_init, der Terminal sollte also bereit sein.
Die ganze Zeit bin ich davon ausgegangen, daß wenn ich die Funktion aus der Dll
geholt habe und das Programm compiliert bei der Angabe der Parameter kein Fehler
mehr vorliegen kann. Durch Probieren habe ich nun gemerkt, daß man sehr wohl
völlig falsche Parameter definieren kann ( Byte statt Pointer )
und keine Exception beim Programmstart auftritt.
Es könnte also sein das es schon an der Definition liegt.

*****************
function CT_init(ctn:word;pn:word):word;stdcall; external 'CTORG32.DLL'
function CT_data(ctn:word;dad:byte;sad:byte;lenc:word;comma nd:pointer;lenr:word;response:pointer):word;stdcal l;external 'CTORG32.DLL';
function CT_close(ctn:word):shortint;stdcall; external 'CTORG32.DLL'
*****************
´
So langsam werde ich ziemlich hilflos.
Das muss doch irgendwie zu machen sein......


Stephan

Wormid 22. Okt 2003 22:20

Re: CT - Api / Chipkarten
 
Wie sieht das mit der Variable "speicher" aus? Ist die mit 2 Bytes groß genug für die Rückgabe? Außerdem muss "lenr" als Variable übergeben werden, weil CT_Data wohl die tatsächliche länge der Antwort in "speicher" angibt.

Gruß

Wormid


P.S. Ansonsten weiss ich allerdings auch nicht weiterr.... :(

negaH 23. Okt 2003 00:41

Re: CT - Api / Chipkarten
 
Zitat:

Delphi-Quellcode:
var
  command: array of byte;
begin
  ...
    Res := CT_Data(ctn, dad, sad, SizeOf(command), @command, lenr, @response);
  ...
end;

SizeOf(Command) = SizeOf(array of Byte) = SizeOf(Pointer) = 4

Statt Sizeof(Command) nimm Length(Command), da Command als dynamisches array of Byte deklariert wurde.

@Command = @Array of Byte = @Pointer = Zeiger auf Zeiger ist ebenfalls falsch. Die CT Library überschreibt somit die internen Verwaltungsdaten des dynamischen Arrays.
Statt @Command benutze bitte @Command[0] oder Pointer(Command).

Gruß Hagen

PS: Ich wusste garnicht das man mir dem CT API Speicherkarten auslesen kann ? Normalerweise konnte man früher nur echte Prozessorkarten über deren ADPU ansprechen !

Wormid 23. Okt 2003 10:12

Re: CT - Api / Chipkarten
 
Öhm... merkt man das, das ich mir im Umgang mit Pointer auch nicht sicher genug bin, um damit auf dem Papier zu programmieren... :oops:

Aber man lernt ja nie aus.

:hi:

skullcrusher 23. Okt 2003 23:02

Re: CT - Api / Chipkarten
 
Halli Hallo !

@wormid : He, das war doch garnicht so schlecht. Trotzdem Danke ....
@Hagen :
Hm, ich habe Deine Änderungen eingebunden aber die Fehlermeldung bleibt die
gleiche. Da scheint irgendwas generelles nicht zu stimmen.
Hast Du mit der CT-Api gearbeitet ?
Könntest Du mir einfach mal eine Rountine geben wie Du CT_data angesprochen hast ?
Ich komme einfach nicht auf meinen Fehler. Ich schätze mal es ist mittlerweile
ein ganz trivialer, ich komme nur nicht dahinter.

Schon mal Danke,

Stephan

negaH 24. Okt 2003 01:07

Re: CT - Api / Chipkarten
 
Nein, ich habe nicht mit der CT API gearbeitet, ich habe sie nur überflogen und analysiert. Für meine Zwecke war sie damals unzureichend und zu kompliziert. Nach meinem Wissenstand konnte die CT API damals überhaupt keine Speicherkarten o.ä. Nicht-Prozessorkarten ansteuern.
Chipkarte ist nicht gleich Chipkarte. Eine Speicherkarte hat ein echt primitiven Aufbau im Vergleich zu Prozessorkarten.


Gruß Hagen

skullcrusher 24. Okt 2003 14:06

Re: CT - Api / Chipkarten
 
Schade,

aber trotzdem vielen Dank für die Hilfestellung.
Vielleicht bin ich auch einfach zu blöd dafür.
Es ist warscheinlich irgendwas total einfaches......

So,Also :
irgendjemand da draussen der jemanden kennt der einen kennt
der schon mal mit der CT-Api und Delphi gearbeitet hat :zwinker: ?

Das wäre toll......

Stephan

PeterRettig 24. Okt 2003 14:41

Re: CT - Api / Chipkarten
 
Ich habe mal in die CT-API geschaut und da ist mir aufgefallen, dass sowohl
command als auch response als Variablentyp iu8 haben, und das ja eigentlich
nicht direkt dem Typ Pointer entspricht!?

Peter

skullcrusher 24. Okt 2003 15:08

Re: CT - Api / Chipkarten
 
Hallo Peter,

hm, bei mir in der Beschreibung der CT-Api steht
command : Referenzadresse eines Feldes mit Elementen vom Typ IU8.
Das Gleiche bei response.
Wo hast Du das gefunden ?
Vielleicht habe ich ja eine falsche Doku.....
Obwohl, ich sehe gerade in der Beschreibung direkt vom Hersteller
des Readers steht:
valid memory adress of field variable holding the chipcard Terminal command.

Stephan

PeterRettig 24. Okt 2003 16:21

Re: CT - Api / Chipkarten
 
Ich habe gerade gesehen, dass das je nach Beschreibung etwas
unterschiedlich ausfällt! Aber ein Blick in die Ctapi.h bringt
für mich endgültige Verwirrung, denn da steht:

char MSWIN_API CT_data (unsigned short ctn, unsigned char * dad,
unsigned char * sad, unsigned short lenc, unsigned char * command,
unsigned short * lenr, unsigned char * response );

Und als Beschreibung:
Input Paramter:
'dad' = Pointer / memory address of variable holding
the "Destination ADdress".
( pointer to "IU8" ("integer unsigned, 8 bit") )
MUST NOT BE 'NULL'!
'sad' = Pointer / memory address of vatiable holding
the "Source ADdress".
( pointer to "IU8" ("integer unsigned, 8 bit") )
MUST NOT BE 'NULL'!
'lenr' = Pointer / memory address of variable holding
the "LENgth Response".
Length of 'reponse'-buffer in bytes.
( pointer to "IU16" ("integer unsigned,
16 bit") )
MUST NOT BE 'NULL'!
u.s.w.
Das heißt also dad, sad, lenr sind auch Pointer auf einen iu8 oder iu16
Typ!? Leider bin ich des Visual Basic nicht mächtig genug um das an dem
Beispielprogramm abzuchecken, aber die Zeile:

Private Declare Function CT_data Lib "CTORG32.DLL" Alias "CTDEORGT1_data" ( _
ByVal ctn As Integer, dad As Byte, sad As Byte, ByVal lenc As Integer, _
command As Byte, lenr As Integer, response As Byte) As Byte

sieht meiner Ansicht nach auch danach aus!

Peter

skullcrusher 25. Okt 2003 14:43

Re: CT - Api / Chipkarten
 
Hm,

das wäre natürlich ein Ding.
Bei mir in der Beschreibung steht definitiv drin das diese Angaben
keine Pointer sind.
Den Header habe ich mir nicht angeschaut, weil ich in den Sprachen sowieso
nicht so fit bin.
Ich werde es aber heute abend mal ausprobieren.
Könnte natürlich die Lösung sein. Würde die EAccessviolation erklären.

Falls es das ist hast Du was bei mir gut !!!!

Stephan

skullcrusher 26. Okt 2003 22:55

Re: CT - Api / Chipkarten
 
Ja,

was soll ich sagen, es sieht wirklich so aus, als ob da meine Beschreibung
was verschweigt.
Nachdem ich mir den header genau angesehen habe muss ich Dir absolut Recht
geben, sowohl dad als auch sad und lenr sind wohl pointer.
Also, das alles flux nach bestem Wissen und Gewissen umgesetzt und
siehe da: Keine EAccessviolation mehr !
Aber es funzt immer noch nicht.
Jetzt bekomme ich als Rückmeldung von 65585.
Als letzte Bitte an alle hier noch einmal über die Pointerdefinitionen
zu schauen, da ich dort echt absoluter Anfänger bin:
Delphi-Quellcode:
// Einbinden der Dll Funktion CT_data
function CT_data(ctn:word;dad:pointer;sad:pointer;lenc:word;command:pointer;lenr:pointer;response:pointer):word;stdcall;external 'CTORG32.DLL';
procedure TForm1.Button3Click(Sender: TObject);
var
daten:kdaten;
rueckgabe:word;
sad,dad:byte;
lenr:word;
commando:array of byte;
speicher:array of byte;
begin
// Select file legt die zu empfangende Datensection fest !
setlength(speicher,22);
setlength(commando,28);
commando[0]:=$00;
commando[1]:=$A4;
commando[2]:=$00;
commando[3]:=$88;
commando[4]:=$02;
commando[5]:=$3F;
commando[6]:=$00;
dad:=02;
sad:=01;
lenr:=28;
rueckgabe:=CT_data(1,@dad,@sad,length(commando),@commando[0],@lenr,@speicher[0]);
showmessage(inttostr(rueckgabe));
end;
Ist das alles logisch ?

Danke und versprochen, ich werde euch dann nicht mehr nerven.
Werde dann alleine weiter kämpfen.

Gruß,

Stephan

PeterRettig 27. Okt 2003 10:03

Re: CT - Api / Chipkarten
 
Hallo Stephan,

der Rückgabewert ist nicht word sondern shortint!
Und wenn ich mich recht erinnere, solltest du dann
statt 255 den Rückgabewert 0 (OK) bekommen.

Peter

Colonel Chris 27. Okt 2003 18:28

Re: CT - Api / Chipkarten
 
Ich hatte das Problem auch. Hast du auch alles mit stdcall aufgerufen? Auf jeden Fall hatte ich ne Zeit lang nur Exceptions. Mein Ansatz war, alles dynamisch aufzurufen und ein simples Exception Handling drüber zu stülpen. Ach, und übrigens: Du darfst die ctapi.dll NICHT UNLOADEN. Mache dein FreeLibrary in den finally-Term der Hauptprozedur! Denn intern wird die ctn gelöscht, sobald du die dll befreist. Dann greift der Aufruf immer ins Leere.

Ich hätte ein paar fertige Stücke Code zu dem Thema (Karte auslesen etc. funktioniert reibungslos), jedoch würde ich vorher gerne erfahren, worin dein Projekt besteht. :?:

Grüße, Chris

skullcrusher 27. Okt 2003 23:04

Re: CT - Api / Chipkarten
 
Hallo Chris,

na da ist ja mal einer der das schon mal unter Delphi gemacht hat.
Ich habe schon tagelang das Netz durchforstet nach Delphi / CT-Api
Kombinationen aber wenn gibt es die Infos nur in VB oder für Linux und
das kann ich alles nicht so gut portieren.
Mit stdcall habe ich schon alles aufgerufen, das stimmt wohl.
Das Problem beschränkt sich auf die Funktion CT_data.
CT_init und CT_close liefert jeweils die 0 als Rückgabewert.
Hm, klar an einer Hilfe in Form von Code wäre ich natürlich sehr
interessiert. Und verständlich ist, das Du vorher wissen willst um was
es geht, am Ende gibst Du Deinen Code her und ein anderer verdient sich damit
eine goldene Nase:
Ein Bekannter hat ein Programm für Ärzte entwickelt.
Da werden jetzt überall diese Chipcardreader eingesetzt. Er braucht die Daten
für sein Programm und fragte mich, ob ich da nicht was programmieren könnte.
Weil es mich brennend interessiert hat habe ich ja gesagt.
Leider bin ich in Sachen Pointer, Dll Aufrufe etc ziemlich unerfahren.
Ich habe mich da jetzt schon ganz schön reingelesen, aber an manchen Stellen
happert es einfach noch ein wenig mit dem Verständnis.
Geld: Es wird wohl dafür nicht viel Geld geben.
Ich hatte mir sowieso schon überlegt, der Community hier was zu spenden (wenn das geht)
falls ich das Problem mit Hilfe von Delphipraxis gelöst bekomme. Man kann ja nicht
immer nur einfach den Honig saugen und dann nichts zurückgeben.
(Ich weiss garnicht ob das geht, aber Geld für neue Hardware oder anderes wird wohl immer
gebraucht)
Wenn Du damit leben kannst kommen wir da zusammen. Das wird dann ganz offiziell gemacht.
Aber wenn Du sagst "ich hätte auch gerne was davon" ist das auch kein Problem.
Nur im Moment kann ich Dir noch nicht sagen ob und wenn ja wie viel es dafür gibt.
Es kann sein, daß ich da was fertig habe und mein Bekannter dann sagt " Ne hat mir
zu lange gedauert, habe es wo anders machen lassen".
Wie gesagt, ich mache es in erster Linie aus Interesse an der Technik und um einfach
Erfahrung zu sammeln.

Bis dann,

Stephan

PS: Code wäre richtig cool !!!

Colonel Chris 27. Okt 2003 23:47

Re: CT - Api / Chipkarten
 
Also gut, mein Code ist auch noch nicht fertig, ich bin momentan dabei, den ATR auszuwerten und dann daraus dynamisch auf das korrekte Ausleseverfahren (bzw. Parserfunktion) für die Karte zu schließen. (ASN.1 oder Festform).

Ich kann dir jedoch die korrekten Header Files als .pas geben. Die sind eh' öffentlich und unterliegen der GPL. OK, die C-Version unterliegt der GPL, aber wir woll'n mal nich so sein. Das eigentliche Programm kann ich dir aber nicht geben, da ich ebenfalls für einen Kumpel ein kommerzielles Plugin schreibe. Beachte, dass ich eine im Ordner vorhandene ctorg32.dll voraussetze. Somit ist das Programm oberflächlich nur zu Orga kompatibel. Die eigentlichen Funktionen sind jedoch alle generisch, so dass eine Änderung des Dateinams genügen sollte. Ich poste hier mal einen Teil des Codes, den Rest gibts wenn du mir ne PN mit deiner Mailaddi schickst.

Colonel Chris 27. Okt 2003 23:51

Re: CT - Api / Chipkarten
 
Einmal die CT_data:

Delphi-Quellcode:
function CT_data( ctn:      Word;
                  dad, sad: PByte;
                  lenc:     Word;
                  command: PByte;
                  lenr:    PWord;
                  response: PByte ): ShortInt;
begin
  Result := ERR_TRANS;
  if @Function_CTdata <> nil
  // now calling function from driver DLL
  then try
    Result := Function_CTdata(ctn,dad,sad,lenc,command,lenr,response);
  except
    Result := ERR_INCOMPATIBLE;
  end;
end;
Und der DLL-Aufruf zu Beginn der Hauptprozedur:
Delphi-Quellcode:
function CTAPI_Load(path: PChar): Integer;
begin
  Result := ERR_UNKNOWN;
  DLLHandle := LoadLibrary(path);
  if DLLHandle <> 0 then begin
    @Function_CTinit := GetProcAddress(DLLHandle, 'CT_init');
    @Function_CTdata := GetProcAddress(DLLHandle, 'CT_data');
    @Function_CTclose:= GetProcAddress(DLLHandle, 'CT_close');
    if (@Function_CTinit = nil) or (@Function_CTdata = nil)
                                or (@Function_CTclose = nil)
    then Result := ERR_INCOMPATIBLE;
  end
  else Result := ERR_LIBRARY;
end;

Colonel Chris 28. Okt 2003 19:10

Re: CT - Api / Chipkarten
 
Hi. Vielleicht wär's auch ganz sinnvoll, wenn du nicht sofort mit dem Select File um dich schlagen würdest. Ohne einen Reset der Karte wird der eh nur Fehlercodes ausgeben.

Also: Mühsam ernährt sich das Eichhörnchen. Fang doch lieber erst mal damit an, das CT zu resetten und den Status abzufragen. Die Definitionen zu den Befehlen findest du im Netz, u.a. bei Sourceforge!

skullcrusher 28. Okt 2003 22:11

Re: CT - Api / Chipkarten
 
Halli Hallo !

Mit einigen Änderungen die ich aus Deinem Code ersehen konnte
habe ich das erste Mal bei CT_data und einem Reset des Gerätes
ein result von 0 !!!

COOL!Vielen Dank !

Ich werde mich jetzt erst mal aufs Ohr hauen, bin nämlich ziemlich
erkältet.

Morgen werde ich mal weiter machen.


Hast Du meine PP bekommen ?
Ich war mir da nämlich nicht so sicher ob das alles funktioniert hat.

Egal,

danke,

Stephan

skullcrusher 28. Okt 2003 22:12

Re: CT - Api / Chipkarten
 
Äh,

ich meine natürlich PN !!
Ah, ab ins Bett..... ;-)

Colonel Chris 28. Okt 2003 22:55

Re: CT - Api / Chipkarten
 
Ist angekommen. Morgen oder übermorgen bekommst du den Code. Hab momentan etwas viel zu tun.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz