[Pcsclite-cvs-commit] HandlerTest/Host handler_test.c,1.3,1.4
rousseau@quantz.debian.org
rousseau@quantz.debian.org
Wed, 29 Oct 2003 22:30:35 +0100
Update of /cvsroot/pcsclite/HandlerTest/Host
In directory quantz:/tmp/cvs-serv29995
Modified Files:
handler_test.c
Log Message:
a lot of new options. See -h for details.
Index: handler_test.c
===================================================================
RCS file: /cvsroot/pcsclite/HandlerTest/Host/handler_test.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- handler_test.c 4 Sep 2003 13:16:36 -0000 1.3
+++ handler_test.c 29 Oct 2003 21:30:33 -0000 1.4
@@ -27,6 +27,7 @@
#include <string.h>
#include <dlfcn.h>
#include <stdlib.h>
+#include <getopt.h>
#include "ifdhandler.h"
#include "debug.h"
@@ -34,6 +35,11 @@
#define LUN 0
#define ENV_LIBNAME "LIB"
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
int handler_test(int lun, int channel);
void pcsc_error(int rv);
int exchange(char *text, DWORD lun, SCARD_IO_HEADER SendPci,
@@ -73,43 +79,115 @@
struct f_t f = { NULL, NULL, NULL, NULL, NULL };
+#define CASE1 (1)
+#define CASE2 (1<<1)
+#define CASE3 (1<<2)
+#define CASE4 (1<<3)
+
+/* flags */
+char full = FALSE;
+int timerequest = -1;
+char cases = 0;
+char tpdu = FALSE;
+char apdu = FALSE;
+
+/* getopt(3) */
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+
+void help(char *argv0)
+{
+ printf("\nUsage: %s [-f] [-t val] [-1] [-2] [-3] [-4] [-A] [-T] libname [channel]\n", argv0);
+ printf(" -f : test APDU with every possible lengths\n");
+ printf(" -t val : use val as timerequest value. Set to 0 to avoid test\n");
+ printf(" -1 : test CASE 1 APDU\n");
+ printf(" -2 : test CASE 2 APDU\n");
+ printf(" -3 : test CASE 3 APDU\n");
+ printf(" -4 : test CASE 4 APDU\n");
+ printf(" -A : use APDU\n");
+ printf(" -T : use TPDU\n");
+ printf(" libname : driver to load\n");
+ printf(" channel : channel to use (for a serial driver)\n\n");
+ printf("example: %s /usr/lib/pcsc/drivers/serial/libGemPC410.so 2\n",
+ argv0);
+ printf(" to load the libGemPC410 and use /dev/pcsc/2\n");
+ printf("or define environment variable LIB\n");
+ printf(" LIB=/usr/lib/pcsc/drivers/serial/libGemPC410.so %s\n", argv0);
+
+ exit(1);
+} /* help */
+
int main(int argc, char *argv[])
{
void *lib_handle = NULL;
int ret;
int channel = 0;
char *driver;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "ft:1234AT")) != EOF)
+ {
+ switch (opt)
+ {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ cases |= 1 << (opt - '1');
+ printf("test case: %c\n", opt);
+ break;
+
+ case 'f':
+ full = TRUE;
+ printf("Full test (all APDU sizes)\n");
+ break;
+
+ case 't':
+ timerequest = atol(optarg);
+ printf("time request: %d\n", timerequest);
+ break;
+
+ case 'A':
+ apdu = TRUE;
+ printf("Use APDU\n");
+ break;
+
+ case 'T':
+ tpdu = TRUE;
+ printf("Use TPDU\n");
+ break;
+
+ default:
+ printf ("caractère: %c (0x%02X)\n", opt, opt);
+ help(argv[0]);
+ }
+ }
driver = getenv(ENV_LIBNAME);
if (driver == NULL)
{
- if (!(argc == 2 || argc == 3))
- {
- printf("Usage: %s libname [channel]\n", argv[0]);
- printf("example: %s /usr/lib/pcsc/drivers/serial/libGemPC410.so 2\n",
- argv[0]);
- printf(" to load the libGemPC410 and use /dev/pcsc/2\n");
- printf("or define environment variable LIB\n");
- printf(" LIB=/usr/lib/pcsc/drivers/serial/libGemPC410.so %s\n",
- argv[0]);
- return 1;
- }
+ if (argc - optind < 1)
+ help(argv[0]);
// driver
- driver = argv[1];
+ driver = argv[optind];
// channel
- if (argc == 3)
- channel = atoi(argv[2]);
+ if (argc - optind >= 2)
+ channel = atoi(argv[optind+1]);
}
else
{
// channel
- if (argc == 2)
- channel = atoi(argv[1]);
+ if (argc - optind > 1)
+ channel = atoi(argv[optind]);
}
+ printf("Using driver: %s\n", driver);
+ printf("Using channel: %d\n", channel);
+
lib_handle = dlopen(driver, RTLD_LAZY);
if (lib_handle == NULL)
{
@@ -141,6 +219,7 @@
int e_length; // expected result length
char *text = NULL;
int time;
+ int start, end;
rv = f.IFDHCreateChannel(lun, channel);
@@ -197,232 +276,359 @@
goto end;
/* Time Request */
- text = "Time Request";
- time = 10;
-
- s[0] = 0x80;
- s[1] = 0x25;
- s[2] = 0x00;
- s[3] = time;
-
- dwSendLength = 4;
- dwRecvLength = sizeof(r);
+ if (timerequest >= 0)
+ {
+ text = "Time Request";
+ time = timerequest;
- e[0] = 0x90;
- e[1] = 0x00;
- e_length = 2;
+ s[0] = 0x80;
+ s[1] = 0x38;
+ s[2] = 0x00;
+ s[3] = time;
- if (exchange(text, lun, SendPci, &RecvPci,
- s, dwSendLength, r, &dwRecvLength, e, e_length))
- goto end;
+ dwSendLength = 4;
+ dwRecvLength = sizeof(r);
- /* Case 1, APDU */
- text = "Case 1, APDU: CLA INS P1 P2, L(Cmd) = 4";
- s[0] = 0x80;
- s[1] = 0x21;
- s[2] = 0x00;
- s[3] = 0x00;
+ e[0] = 0x90;
+ e[1] = 0x00;
+ e_length = 2;
- dwSendLength = 4;
- dwRecvLength = sizeof(r);
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
+ }
- e[0] = 0x90;
- e[1] = 0x00;
- e_length = 2;
+ if (cases & CASE1)
+ {
+ /* Case 1, APDU */
+ text = "Case 1, APDU: CLA INS P1 P2, L(Cmd) = 4";
+ s[0] = 0x80;
+ s[1] = 0x30;
+ s[2] = 0x00;
+ s[3] = 0x00;
- if (exchange(text, lun, SendPci, &RecvPci,
- s, dwSendLength, r, &dwRecvLength, e, e_length))
- goto end;
+ dwSendLength = 4;
+ dwRecvLength = sizeof(r);
- /* Case 1, TPDU */
- text = "Case 1, TPDU: CLA INS P1 P2 P3 (=0), L(Cmd) = 5";
- s[0] = 0x80;
- s[1] = 0x21;
- s[2] = 0x00;
- s[3] = 0x00;
- s[4] = 0x00;
+ e[0] = 0x90;
+ e[1] = 0x00;
+ e_length = 2;
- dwSendLength = 5;
- dwRecvLength = sizeof(r);
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
- e[0] = 0x90;
- e[1] = 0x00;
- e_length = 2;
+ /* Case 1, TPDU */
+ text = "Case 1, TPDU: CLA INS P1 P2 P3 (=0), L(Cmd) = 5";
+ s[0] = 0x80;
+ s[1] = 0x30;
+ s[2] = 0x00;
+ s[3] = 0x00;
+ s[4] = 0x00;
- if (exchange(text, lun, SendPci, &RecvPci,
- s, dwSendLength, r, &dwRecvLength, e, e_length))
- goto end;
+ dwSendLength = 5;
+ dwRecvLength = sizeof(r);
- /* Case 2 */
- /*
- * 248 (0xF8) is max size for one USB or GBP paquet
- * 255 (0xFF) maximum, 1 minimum
- */
- text = "Case 2: CLA INS P1 P2 Le, L(Cmd) = 5";
- len_i = 255;
+ e[0] = 0x90;
+ e[1] = 0x00;
+ e_length = 2;
- s[0] = 0x80;
- s[1] = 0x22;
- s[2] = 0x00;
- s[3] = 0x00;
- s[4] = len_i;
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
+ }
- for (i=0; i<len_i; i++)
- s[5+i] = i;
+ if (cases & CASE2)
+ {
+ /* Case 2 */
+ /*
+ * 248 (0xF8) is max size for one USB or GBP paquet
+ * 255 (0xFF) maximum, 1 minimum
+ */
+ text = "Case 2: CLA INS P1 P2 Le, L(Cmd) = 5";
+ start = end = 255;
+ if (full)
+ start = 1;
- dwSendLength = len_i + 5;
- dwRecvLength = sizeof(r);
+ for (len_i = start; len_i <= end; len_i++)
+ {
+ s[0] = 0x80;
+ s[1] = 0x32;
+ s[2] = 0x00;
+ s[3] = 0x00;
+ s[4] = len_i;
- e[0] = 0x90;
- e[1] = 0x00;
- e_length = 2;
+ for (i=0; i<len_i; i++)
+ s[5+i] = i;
- if (exchange(text, lun, SendPci, &RecvPci,
- s, dwSendLength, r, &dwRecvLength, e, e_length))
- goto end;
+ dwSendLength = len_i + 5;
+ dwRecvLength = sizeof(r);
- /* Case 3 */
- /*
- * 252 (0xFC) is max size for one USB or GBP paquet
- * 256 (0x100) maximum, 1 minimum
- */
- text = "Case 3: CLA INS P1 P2 Lc Data, L(Cmd) = 5 + Lc";
- len_o = 256;
+ e[0] = 0x90;
+ e[1] = 0x00;
+ e_length = 2;
- s[0] = 0x80;
- s[1] = 0x23;
- if (len_o > 255)
- {
- s[2] = 0x01;
- s[3] = len_o-256;
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
+ }
}
- else
+
+ if (cases & CASE3)
{
- s[2] = 0x00;
- s[3] = len_o;
- }
- s[4] = len_o;
+ /* Case 3 */
+ /*
+ * 252 (0xFC) is max size for one USB or GBP paquet
+ * 256 (0x100) maximum, 1 minimum
+ */
+ text = "Case 3: CLA INS P1 P2 Lc Data, L(Cmd) = 5 + Lc";
+ start = end = 255;
+ if (full)
+ start = 1;
- dwSendLength = 5;
- dwRecvLength = sizeof(r);
+ for (len_o = start; len_o <= end; len_o++)
+ {
+ s[0] = 0x80;
+ s[1] = 0x34;
+ if (len_o > 255)
+ {
+ s[2] = 0x01;
+ s[3] = len_o-256;
+ }
+ else
+ {
+ s[2] = 0x00;
+ s[3] = len_o;
+ }
+ s[4] = len_o;
- for (i=0; i<len_o; i++)
- e[i] = i;
- e[i++] = 0x90;
- e[i++] = 0x00;
- e_length = len_o+2;
+ dwSendLength = 5;
+ dwRecvLength = sizeof(r);
- if (exchange(text, lun, SendPci, &RecvPci,
- s, dwSendLength, r, &dwRecvLength, e, e_length))
- goto end;
+ for (i=0; i<len_o; i++)
+ e[i] = i;
+ e[i++] = 0x90;
+ e[i++] = 0x00;
+ e_length = len_o+2;
- /* Case 4, TPDU */
- /*
- * len_i
- * 248 (0xF8) is max size for one USB or GBP paquet
- * 255 (0xFF) maximum, 1 minimum
- *
- * len_o
- * 252 (0xFC) is max size for one USB or GBP paquet
- * 256 (0x100) maximum, 1 minimum
- */
- text = "Case 4, TPDU: CLA INS P1 P2 Lc Data, L(Cmd) = 5 + Lc";
- len_i = 2; //255;
- len_o = 3; //256;
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
+ }
- s[0] = 0x80;
- s[1] = 0x24;
- if (len_o > 255)
- {
- s[2] = 0x01;
- s[3] = len_o-256;
+#if 0
+ /* Case 3, length too short */
+ text = "Case 3, length too short: CLA INS P1 P2 Lc Data, L(Cmd) = 5 + Lc";
+ len_o = 20;
+
+ s[0] = 0x80;
+ s[1] = 0x3C;
+ if (len_o > 255)
+ {
+ s[2] = 0x01;
+ s[3] = len_o-256;
+ }
+ else
+ {
+ s[2] = 0x00;
+ s[3] = len_o;
+ }
+ s[4] = len_o-10;
+
+ dwSendLength = 5;
+ dwRecvLength = sizeof(r);
+
+ if (tpdu)
+ {
+ for (i=0; i<len_o; i++)
+ e[i] = i;
+ e[i++] = 0x90;
+ e[i++] = 0x00;
+ e_length = len_o+2;
+ }
+ else
+ {
+ e[0] = 0x6C;
+ e[1] = len_o;
+ e_length = 2;
+ }
+
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
+#endif
+
+#if 0
+ /* Case 3, length too long */
+ text = "Case 3, length too long: CLA INS P1 P2 Lc Data, L(Cmd) = 5 + Lc";
+ len_o = 20;
+
+ s[0] = 0x80;
+ s[1] = 0x3C;
+ if (len_o > 255)
+ {
+ s[2] = 0x01;
+ s[3] = len_o-256;
+ }
+ else
+ {
+ s[2] = 0x00;
+ s[3] = len_o;
+ }
+ s[4] = len_o+10;
+
+ dwSendLength = 5;
+ dwRecvLength = sizeof(r);
+
+ if (tpdu)
+ {
+ for (i=0; i<len_o; i++)
+ e[i] = i;
+ e[i++] = 0x90;
+ e[i++] = 0x00;
+ e_length = len_o+2;
+ }
+ else
+ {
+ e[0] = 0x6C;
+ e[1] = len_o;
+ e_length = 2;
+ }
+
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
+#endif
}
- else
+
+ if (cases & CASE4)
{
- s[2] = 0x00;
- s[3] = len_o;
- }
- s[4] = len_i;
+ if (tpdu)
+ {
+ /* Case 4, TPDU */
+ /*
+ * len_i
+ * 248 (0xF8) is max size for one USB or GBP paquet
+ * 255 (0xFF) maximum, 1 minimum
+ *
+ * len_o
+ * 252 (0xFC) is max size for one USB or GBP paquet
+ * 256 (0x100) maximum, 1 minimum
+ */
+ start = end = 255;
+ if (full)
+ start = 1;
- for (i=0; i<len_i; i++)
- s[5+i] = i;
+ for (len_i = start; len_i <= end; len_i++)
+ {
+ text = "Case 4, TPDU: CLA INS P1 P2 Lc Data, L(Cmd) = 5 + Lc";
+ len_o = 256 - len_i;
- dwSendLength = len_i + 5;
- dwRecvLength = sizeof(r);
+ s[0] = 0x80;
+ s[1] = 0x36;
+ if (len_o > 255)
+ {
+ s[2] = 0x01;
+ s[3] = len_o-256;
+ }
+ else
+ {
+ s[2] = 0x00;
+ s[3] = len_o;
+ }
+ s[4] = len_i;
- e[0] = 0x61;
- e[1] = len_o & 0xFF;
- e_length = 2;
+ for (i=0; i<len_i; i++)
+ s[5+i] = i;
- if (exchange(text, lun, SendPci, &RecvPci,
- s, dwSendLength, r, &dwRecvLength, e, e_length))
- goto end;
+ dwSendLength = len_i + 5;
+ dwRecvLength = sizeof(r);
- /* Get response */
- text = "Case 4, TPDU, Get response: ";
- s[0] = 0x00;
- s[1] = 0xC0;
- s[2] = 0x00;
- s[3] = 0x00;
- s[4] = r[1]; /* SW2 of previous command */
+ e[0] = 0x61;
+ e[1] = len_o & 0xFF;
+ e_length = 2;
- dwSendLength = 5;
- dwRecvLength = sizeof(r);
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
- for (i=0; i<len_o; i++)
- e[i] = i;
- e[i++] = 0x90;
- e[i++] = 0x00;
- e_length = len_o+2;
+ /* Get response */
+ text = "Case 4, TPDU, Get response: ";
+ s[0] = 0x80;
+ s[1] = 0xC0;
+ s[2] = 0x00;
+ s[3] = 0x00;
+ s[4] = r[1]; /* SW2 of previous command */
- if (exchange(text, lun, SendPci, &RecvPci,
- s, dwSendLength, r, &dwRecvLength, e, e_length))
- goto end;
+ dwSendLength = 5;
+ dwRecvLength = sizeof(r);
- /* Case 4, APDU */
- /*
- * len_i
- * 248 (0xF8) is max size for one USB or GBP paquet
- * 255 (0xFF) maximum, 1 minimum
- *
- * len_o
- * 252 (0xFC) is max size for one USB or GBP paquet
- * 256 (0x100) maximum, 1 minimum
- */
- text = "Case 4, APDU: CLA INS P1 P2 Lc Data Le, L(Cmd) = 5 + Lc +1";
- len_i = 2; //255;
- len_o = 3; //256;
+ for (i=0; i<len_o; i++)
+ e[i] = i;
+ e[i++] = 0x90;
+ e[i++] = 0x00;
+ e_length = len_o+2;
- s[0] = 0x80;
- s[1] = 0x24;
- if (len_o > 255)
- {
- s[2] = 0x01;
- s[3] = len_o-256;
- }
- else
- {
- s[2] = 0x00;
- s[3] = len_o;
- }
- s[4] = len_i;
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
+ }
+ }
- for (i=0; i<len_i; i++)
- s[5+i] = i;
- s[5+len_i] = len_o & 0xFF;
+ if (apdu)
+ {
+ /* Case 4, APDU */
+ /*
+ * len_i
+ * 248 (0xF8) is max size for one USB or GBP paquet
+ * 255 (0xFF) maximum, 1 minimum
+ *
+ * len_o
+ * 252 (0xFC) is max size for one USB or GBP paquet
+ * 256 (0x100) maximum, 1 minimum
+ */
+ text = "Case 4, APDU: CLA INS P1 P2 Lc Data Le, L(Cmd) = 5 + Lc +1";
+ start = end = 255;
+ if (full)
+ start = 1;
- dwSendLength = len_i + 6;
- dwRecvLength = sizeof(r);
+ for (len_i = start; len_i <= end; len_i++)
+ {
+ len_o = 256 - len_i;
- for (i=0; i<len_o; i++)
- e[i] = i;
- e[i++] = 0x90;
- e[i++] = 0x00;
- e_length = len_o+2;
+ s[0] = 0x80;
+ s[1] = 0x36;
+ if (len_o > 255)
+ {
+ s[2] = 0x01;
+ s[3] = len_o-256;
+ }
+ else
+ {
+ s[2] = 0x00;
+ s[3] = len_o;
+ }
+ s[4] = len_i;
- if (exchange(text, lun, SendPci, &RecvPci,
- s, dwSendLength, r, &dwRecvLength, e, e_length))
- goto end;
+ for (i=0; i<len_i; i++)
+ s[5+i] = i;
+ s[5+len_i] = len_o & 0xFF;
+
+ dwSendLength = len_i + 6;
+ dwRecvLength = sizeof(r);
+
+ for (i=0; i<len_o; i++)
+ e[i] = i;
+ e[i++] = 0x90;
+ e[i++] = 0x00;
+ e_length = len_o+2;
+
+ if (exchange(text, lun, SendPci, &RecvPci,
+ s, dwSendLength, r, &dwRecvLength, e, e_length))
+ goto end;
+ }
+ }
+ }
end:
/* Close */
@@ -485,12 +691,20 @@
return 1;
}
- for (i=0; i<e_length; i++)
+ /* check the received data */
+ for (i=0; i<*r_length; i++)
if (r[i] != e[i])
{
printf("ERROR byte %d: expected 0x%02X, got 0x%02X\n", i, e[i], r[i]);
return 1;
}
+
+ /* check the received length */
+ if (*r_length != e_length)
+ {
+ printf("ERROR: Expected %d bytes and received %ld\n", e_length, *r_length);
+ return 1;
+ }
printf("--------> OK\n");