Autor Beitrag
Flitzs
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 123
Erhaltene Danke: 7

Win7 x64/86 WinServer 2008 R2 x64
C#/C++/C VS2010
BeitragVerfasst: Sa 01.08.09 23:48 
Hallo,

ich hab mir heute ein Chipkarten Lese- und Schreibgerät gekauft und versuche dieses über die CTAPI anzusteueren.

Mein bisheriger Code:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
        [DllImport("CTRSCT32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern sbyte CT_data(ushort ctn, ref byte dad, ref byte sad, ushort lenc, byte[] command, ref ushort lenr, IntPtr response);

        [DllImport("CTRSCT32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern sbyte CT_close(ushort ctn);

        [DllImport("CTRSCT32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern sbyte CT_init(ushort TerminalNumber, ushort COMPort);


        /// <summary>
        /// Führt einen Befehl mit der CTAPI aus
        /// </summary>
        /// <param name="command">Der Befehl</param>
        /// <param name="CardTerminalNumber">Die CardTerminalNummer</param>
        /// <param name="COMPort">Der COM-Port des Gerätes</param>
        /// <param name="MaxResponseLength">Die Maximale Anzahl an Bytes für die Antwort</param>
        /// <param name="ToHost">Gibt an ob der Addresswert für Host oder RemoteHost verwendet werden soll</param>
        /// <param name="ToReader">Bestimmt, ob der Befehl an das Terminal oder an die Karte geht</param>
        /// <returns>Die Antwort des Gerätes</returns>
        private byte[] ExecCommand(byte[] command, ushort CardTerminalNumber, ushort COMPort, ushort MaxResponseLength, bool ToHost, bool ToReader)
        {

            //Verbindung Initialisieren
            sbyte initret = CT_init(CardTerminalNumber, COMPort);
            if (initret != 0)
                throw new Exception("Fehler beim Iniziailisieren. ErrorCode = " + initret);


            //Lege ResponseBuffer an
            ushort responseLength = MaxResponseLength;
            IntPtr responseBuffer = Marshal.AllocHGlobal(responseLength); 


            //Addressen festlegen
            byte SourceAddress = (ToHost ? (byte)2 : (byte)5);      
            byte DestinationAddress = (ToReader ? (byte)1 : (byte)0);                                  

            //CommandArray prüfen
            if (command.Length > ushort.MaxValue)
                throw new ArgumentOutOfRangeException("Der Command ist zu lang!");                          

             //Command ausführen
            sbyte Commandret = CT_data(CardTerminalNumber, ref DestinationAddress, ref SourceAddress, (ushort)command.Length, command, ref responseLength, responseBuffer);
            //Verbindung schließen
            sbyte Closeret = CT_close(CardTerminalNumber);

            if (Commandret != 0)
                throw new Exception("Fehler beim ausführen des Commands. ErrorCode = " + Commandret );

            if(Closeret != 0)
                throw new Exception("Fehler beim schließen der Verbindung. ErrorCode = " + Closeret );
                         
            //ResponseArray erzeugen
            byte[] response = new byte[responseLength];
            //Daten kopieren
            Marshal.Copy(responseBuffer, response, 0, responseLength);
            //Speicherplatz freigeben
            Marshal.FreeHGlobal(responseBuffer);
            return response;
        }


Diese Funktion hab ich mir aus den C/C++ Beispielen zusammengebastelt die ich so im Internet gefunden habe und soweit ich beurteilen kann funktioniert diese auch.

Wenn ich REQUEST ICC
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
   ushort CardTerminalNumber = 1;
            ushort COMPort = 1;
            byte[] Command = new byte[] { 0x200x120x010x000x00 };
            //                            CLA   INS    P1    P2    LE
            byte[] Response = ExecCommand(Command, CardTerminalNumber, COMPort, 1000truetrue);


an das Gerät schicke, bekomme ich bei

  • eingelegter Karte: 144; 1
  • ohne Karte: 98; 0

als Antwort, daher nehme ich an dass die Funktioniert funktioniert :lol:.

Doch leider konnte ich nirgendswo die Befehle für das auslesen / das schreiben auf die Karte finden.

Darum frage ich hier ob jemand eine Seite kennt wo ich die Befehle herbekomme oder sonst irgendeine Bezugsquelle kennt.

mfg Flitzs