source: trunk/src/ifd/ifd-gempc.c @ 964

Revision 964, 18.9 KB checked in by aj, 5 years ago (diff)

indent changes only.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * Reader Drivers for GemPC devices.
3 * Work in progress, entirely untested.
4 *
5 * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
6 */
7
8#include "internal.h"
9#include <unistd.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define GPC_ISO_INPUT_MAX       248
15#define GPC_ISO_EXCHANGE_MAX    254
16#define GPC_MODE_ROS            0x08
17#define GPC_MODE_TLP            0x01
18
19typedef struct gpc_status {
20        /* We need a GBP driver to talk to serial readers */
21        ifd_protocol_t *p;
22        int icc_proto;
23        int card_state;
24        unsigned char cmd_buf[260];
25        size_t cmd_len;
26} gpc_status_t;
27
28static int gpc_transceive(ifd_reader_t *, unsigned int,
29                          const unsigned char *, size_t,
30                          unsigned char *, size_t, long);
31static int gpc_transceive_t0(ifd_reader_t *, unsigned int,
32                             const unsigned char *, size_t,
33                             unsigned char *, size_t);
34static int gpc_transceive_t1(ifd_reader_t *, unsigned int,
35                             const unsigned char *, size_t,
36                             unsigned char *, size_t);
37static int gpc_iso_output(ifd_reader_t *,
38                          const unsigned char *, size_t,
39                          unsigned char *, size_t);
40static int gpc_iso_input(ifd_reader_t *,
41                         const unsigned char *, size_t,
42                         unsigned char *, size_t);
43static int gpc_iso_exchange_apdu(ifd_reader_t *,
44                                 const unsigned char *, size_t,
45                                 unsigned char *, size_t);
46static int gpc_set_serial(ifd_reader_t *, unsigned int, int, int);
47static int gpc_set_mode(ifd_reader_t *, int);
48static int gpc_get_os_version(ifd_reader_t *, char *, size_t);
49static int gpc_command(ifd_reader_t *, const void *, size_t, void *, size_t);
50static int __gpc_command(ifd_reader_t *,
51                         const void *, size_t, void *, size_t, int *);
52static const char *gpc_strerror(int status);
53
54/*
55 * Initialize the reader
56 */
57static int gpc_open(ifd_reader_t * reader, const char *device_name)
58{
59        char buffer[256];
60        gpc_status_t *st;
61        ifd_device_t *dev;
62        int r;
63
64        ifd_debug(1, "called, device=%s", device_name);
65
66        reader->name = "Gemplus Reader (pre-alpha, untested)";
67        reader->nslots = 1;
68
69        if (!(dev = ifd_device_open(device_name)))
70                return IFD_ERROR_GENERIC;
71        reader->device = dev;
72
73        st = (gpc_status_t *) calloc(1, sizeof(*st));
74        if (!st) {
75                ct_error("out of memory");
76                return IFD_ERROR_NO_MEMORY;
77        }
78        reader->driver_data = st;
79
80        if (dev->type == IFD_DEVICE_TYPE_SERIAL) {
81                ifd_device_params_t params;
82
83                if (ifd_device_get_parameters(dev, &params) < 0)
84                        return IFD_ERROR_GENERIC;
85
86                params.serial.speed = 9600;
87                params.serial.bits = 8;
88                params.serial.stopbits = 1;
89                params.serial.parity = IFD_SERIAL_PARITY_NONE;
90
91                if ((r = ifd_device_set_parameters(dev, &params)) < 0)
92                        return r;
93
94                /* Instantiate a GBP driver for this reader */
95                if (!(st->p = ifd_protocol_new(IFD_PROTOCOL_GBP, reader, 0))) {
96                        /* Something is badly hosed */
97                        ct_error("unable to get GBP protocol handler");
98                        return IFD_ERROR_GENERIC;
99                }
100
101                /* Tell the reader to switch to 38400 bps
102                 * If the reader is already at 38400 bps, this
103                 * command will fail, because we're currently
104                 * driving the serial line at 9600. So don't even
105                 * bother with checking the return value.
106                 * Instead, pause for a moment.
107                 */
108                gpc_set_serial(reader, 38400, 8, IFD_SERIAL_PARITY_NONE);
109                usleep(500000);
110                ifd_device_flush(dev);
111                params.serial.speed = 38400;
112                if ((r = ifd_device_set_parameters(dev, &params)) < 0)
113                        return r;
114
115                /* The line should now operate at 38400 */
116                r = gpc_set_mode(reader, GPC_MODE_ROS);
117                if (r < 0 && r != IFD_ERROR_NOT_SUPPORTED)
118                        return r;
119        } else {
120                ct_error("USB devices not yet supported for GemPC readers\n");
121                return -1;
122                /*
123                   sleep(1);
124                   ifd_device_flush(dev);
125                 */
126        }
127
128        r = gpc_get_os_version(reader, buffer, sizeof(buffer));
129        if (r >= 0) {
130                if (!strcmp(buffer, "OROS-R2.24RM"))
131                        reader->name = "GCR 400";
132                else if (!strcmp(buffer, "OROS-R2.99-R1.10"))
133                        reader->name = "GCR 410";
134                else if (!strcmp(buffer, "OROS-R2.99-R1.11"))
135                        reader->name = "GCR 410P";
136                else if (!strcmp(buffer, "OROS-R2.99-R1.21") ||
137                         !strcmp(buffer, "GemCore-R1.21-GM"))
138                        reader->name = "GemPC 410";
139                else if (!strcmp(buffer, "OROS-R2.99-R1.32"))
140                        reader->name = "GemPC 413";
141                ifd_debug(1,
142                          "OS version \"%s\", reader identified as \"%s\"\n",
143                          buffer, reader->name);
144        }
145
146        return 0;
147}
148
149/*
150 * Activate the reader
151 */
152static int gpc_activate(ifd_reader_t * reader)
153{
154        ifd_debug(1, "called.");
155        return 0;
156}
157
158static int gpc_deactivate(ifd_reader_t * reader)
159{
160        return 0;
161}
162
163static int gpc_close(ifd_reader_t * reader)
164{
165        return 0;
166}
167
168/*
169 * Check card status
170 */
171static int gpc_card_status(ifd_reader_t * reader, int slot, int *status)
172{
173        gpc_status_t *st = (gpc_status_t *) reader->driver_data;
174        unsigned char byte;
175        int r;
176
177        if (slot != 0) {
178                ct_error("gempc: bad slot index %u", slot);
179                return IFD_ERROR_INVALID_SLOT;
180        }
181
182        if ((r = gpc_command(reader, "\x17", 1, &byte, 1)) < 0)
183                return r;
184
185        ifd_debug(4, "card %spresent%s\n",
186                  (byte & 0x04) ? "" : "not ",
187                  (byte & 0x02) ? ", powered up" : "");
188
189        *status = (byte & 0x04) ? IFD_CARD_PRESENT : 0;
190
191        /* A power up/down transition can be used to detect
192         * a card change. */
193        if ((st->card_state & 0x02) && !(byte & 0x02))
194                *status |= IFD_CARD_STATUS_CHANGED;
195
196        st->card_state = byte;
197        return 0;
198}
199
200/*
201 * Reset the card and get the ATR
202 */
203static int gpc_card_reset(ifd_reader_t * reader, int slot, void *atr,
204                          size_t size)
205{
206        static unsigned char reset_auto_pps[] = { 0x12, 0x23 };
207        static unsigned char reset_no_pps[] = { 0x12, 0x13 };
208        static unsigned char reset_emv[] = { 0x12 };
209        static unsigned char set_mode[] = { 0x17, 0x00, 0x47 };
210        int r, status;
211
212        ifd_debug(1, "called.");
213
214        if (slot != 0) {
215                ct_error("gempc: bad slot index %u", slot);
216                return IFD_ERROR_INVALID_SLOT;
217        }
218
219        /* Get the card status */
220        if ((r = gpc_card_status(reader, slot, &status)) < 0)
221                return r;
222
223        if (!(status & IFD_CARD_PRESENT))
224                return IFD_ERROR_NO_CARD;
225
226        r = __gpc_command(reader, reset_auto_pps, sizeof(reset_auto_pps),
227                          atr, size, &status);
228        if (r < 0 || status == 0x00)
229                return r;
230
231        /* Try again without PPS */
232        r = __gpc_command(reader, reset_no_pps, sizeof(reset_no_pps),
233                          atr, size, &status);
234        if (r < 0 || status == 0x00)
235                return r;
236
237        /* Try EMV mode */
238        r = __gpc_command(reader, reset_emv, sizeof(reset_emv),
239                          atr, size, &status);
240        if (r < 0 || status == 0x00)
241                return r;
242
243        /* Change Operation Mode, and retry EMV reset */
244        (void)gpc_command(reader, set_mode, sizeof(set_mode), NULL, 0);
245        r = __gpc_command(reader, reset_emv, sizeof(reset_emv),
246                          atr, size, &status);
247        if (r < 0 || status == 0x00)
248                return r;
249
250        return IFD_ERROR_NO_CARD;
251}
252
253/*
254 * Select the card protocol
255 */
256static int gpc_set_protocol(ifd_reader_t * reader, int nslot, int proto)
257{
258        gpc_status_t *st = (gpc_status_t *) reader->driver_data;
259        ifd_slot_t *slot;
260
261        ifd_debug(1, "called, proto=%d", proto);
262
263        if (proto != IFD_PROTOCOL_T0 && proto != IFD_PROTOCOL_T1) {
264                /* XXX FIXME - we need to call DEFINE CARD TYPE here */
265                return IFD_ERROR_NOT_SUPPORTED;
266        }
267
268        slot = &reader->slot[nslot];
269        slot->proto = ifd_protocol_new(IFD_PROTOCOL_TRANSPARENT,
270                                       reader, slot->dad);
271        if (slot->proto == NULL) {
272                ct_error("%s: internal error", reader->name);
273                return IFD_ERROR_GENERIC;
274        }
275
276        st->icc_proto = proto;
277        return 0;
278}
279
280/*
281 * Change the serial speed
282 */
283static int gpc_set_serial(ifd_reader_t * reader, unsigned int speed, int cs,
284                          int parity)
285{
286        unsigned char cmd[] = { 0x0A, 0x00 };
287
288        ifd_debug(1, "called, speed=%u, cs=%d, parity=%d\n", speed, cs, parity);
289
290        if (reader->device->type != IFD_DEVICE_TYPE_SERIAL)
291                return IFD_ERROR_NOT_SUPPORTED;
292
293        switch (speed) {
294        case 1200:
295                cmd[1] = 0x07;
296                break;
297        case 2400:
298                cmd[1] = 0x06;
299                break;
300        case 4800:
301                cmd[1] = 0x05;
302                break;
303        case 9600:
304                cmd[1] = 0x04;
305                break;
306        case 19200:
307                cmd[1] = 0x03;
308                break;
309        case 38400:
310                cmd[1] = 0x02;
311                break;
312        case 76800:
313                cmd[1] = 0x01;
314                break;
315        default:
316                return IFD_ERROR_NOT_SUPPORTED;
317        }
318
319        switch (cs) {
320        case 7:
321                cmd[1] |= 0x08;
322                break;
323        case 8:
324                break;
325        default:
326                return IFD_ERROR_NOT_SUPPORTED;
327        }
328
329        switch (parity) {
330        case IFD_SERIAL_PARITY_EVEN:
331                cmd[1] |= 0x10;
332                break;
333        case IFD_SERIAL_PARITY_NONE:
334                break;
335        default:
336                return IFD_ERROR_NOT_SUPPORTED;
337        }
338
339        return gpc_command(reader, cmd, sizeof(cmd), NULL, 0);
340}
341
342/*
343 * Set Reader mode
344 */
345static int gpc_set_mode(ifd_reader_t * reader, int mode)
346{
347        unsigned char cmd[] = { 0x01, 0x00, 0x00 };
348
349        cmd[2] = mode;
350        return gpc_command(reader, cmd, sizeof(cmd), NULL, 0);
351}
352
353#if 0
354/*
355 * Send command to IFD
356 *
357 * FIXME: we really need a better mechanism at the reader driver
358 * API to allow for a "transceive" operation.
359 */
360static int gpc_send(ifd_reader_t * reader, unsigned int dad,
361                    const unsigned char *buffer, size_t len)
362{
363        gpc_status_t *st = (gpc_status_t *) reader->driver_data;
364
365        ifd_debug(3, "data:%s", ct_hexdump(buffer, len));
366
367        if (len > sizeof(st->cmd_buf))
368                return IFD_ERROR_BUFFER_TOO_SMALL;
369        memcpy(st->cmd_buf, buffer, len);
370        st->cmd_len = len;
371        return 0;
372}
373
374static int gpc_recv(ifd_reader_t * reader, unsigned int dad,
375                    unsigned char *res_buf, size_t res_len, long timeout)
376{
377        gpc_status_t *st = (gpc_status_t *) reader->driver_data;
378        int rc;
379
380        rc = gpc_transceive(reader, dad,
381                            st->cmd_buf, st->cmd_len,
382                            res_buf, res_len, timeout);
383
384        if (rc > 0)
385                ifd_debug(3, "received:%s", ct_hexdump(res_buf, rc));
386        return rc;
387}
388#endif
389
390static int gpc_transparent(ifd_reader_t * reader, int nad, const void *cmd_buf,
391                           size_t cmd_len, void *res_buf, size_t res_len)
392{
393        return gpc_transceive(reader, nad,
394                              (const unsigned char *)cmd_buf, cmd_len,
395                              (unsigned char *)res_buf, res_len, 0);
396}
397
398/*
399 * Generic transceive function
400 */
401static int gpc_transceive(ifd_reader_t * reader, unsigned int dad,
402                          const unsigned char *cmd_buf, size_t cmd_len,
403                          unsigned char *res_buf, size_t res_len, long timeout)
404{
405        gpc_status_t *st = (gpc_status_t *) reader->driver_data;
406        ifd_protocol_t *proto = reader->slot[0].proto;
407        long orig_timeout = 0;
408        int rc;
409
410        if (timeout) {
411                ifd_protocol_get_parameter(proto,
412                                           IFD_PROTOCOL_RECV_TIMEOUT,
413                                           &orig_timeout);
414                ifd_protocol_set_parameter(proto,
415                                           IFD_PROTOCOL_RECV_TIMEOUT,
416                                           timeout * 1000);
417        }
418
419        switch (st->icc_proto) {
420        case IFD_PROTOCOL_T0:
421                rc = gpc_transceive_t0(reader, dad,
422                                       cmd_buf, cmd_len, res_buf, res_len);
423                break;
424        case IFD_PROTOCOL_T1:
425                rc = gpc_transceive_t1(reader, dad,
426                                       cmd_buf, cmd_len, res_buf, res_len);
427                break;
428        default:
429                ct_error("protocol not supported\n");
430                rc = IFD_ERROR_NOT_SUPPORTED;
431        }
432
433        if (orig_timeout) {
434                ifd_protocol_set_parameter(proto,
435                                           IFD_PROTOCOL_RECV_TIMEOUT,
436                                           orig_timeout);
437        }
438
439        return rc;
440}
441
442static int gpc_transceive_t0(ifd_reader_t * reader, unsigned int dad,
443                             const unsigned char *cmd_buf, size_t cmd_len,
444                             unsigned char *res_buf, size_t res_len)
445{
446        ifd_iso_apdu_t iso;
447        int rc;
448
449        if ((rc = ifd_iso_apdu_parse(cmd_buf, cmd_len, &iso)) < 0)
450                return rc;
451
452        switch (iso.cse) {
453        case IFD_APDU_CASE_1:
454        case IFD_APDU_CASE_3S:
455                rc = gpc_iso_input(reader, cmd_buf, cmd_len, res_buf, res_len);
456                break;
457        case IFD_APDU_CASE_2S:
458                rc = gpc_iso_output(reader, cmd_buf, cmd_len, res_buf, res_len);
459                break;
460        case IFD_APDU_CASE_4S:
461                /* The PC/SC IFD driver does an ISO EXCHANGE APDU here,
462                 * but the specs I have say you can do this command only
463                 * for T=1 cards.
464                 * However, we shouldn't get here anyway for T=1, as the
465                 * T=0 protocol driver splits case 4 APDUs. */
466                rc = gpc_iso_exchange_apdu(reader, cmd_buf, cmd_len,
467                                           res_buf, res_len);
468                break;
469        default:
470                ifd_debug(1, "Bad APDU (case %d unknown or unsupported)\n",
471                          iso.cse);
472                return IFD_ERROR_INVALID_ARG;
473        }
474
475        return rc;
476}
477
478static int gpc_transceive_t1(ifd_reader_t * reader, unsigned int dad,
479                             const unsigned char *cmd_buf, size_t cmd_len,
480                             unsigned char *res_buf, size_t res_len)
481{
482        return gpc_iso_exchange_apdu(reader, cmd_buf, cmd_len,
483                                     res_buf, res_len);
484}
485
486/*
487 * Send partial APDU to the card
488 */
489static int gpc_iso_send_frag(ifd_reader_t * reader, unsigned char cmd,
490                             const unsigned char *cmd_buf, size_t cmd_len)
491{
492        unsigned char buffer[256];
493
494        ifd_debug(4, "called, len=%u", cmd_len);
495        if (cmd_len > sizeof(buffer) - 6)
496                return IFD_ERROR_INVALID_ARG;
497
498        buffer[0] = cmd;
499        buffer[1] = 0xFF;
500        buffer[2] = 0xFF;
501        buffer[3] = 0xFF;
502        buffer[4] = 0xFF;
503        buffer[5] = cmd_len;
504        memcpy(buffer + 6, cmd_buf, cmd_len);
505
506        return gpc_command(reader, buffer, 6 + cmd_len, buffer, sizeof(buffer));
507}
508
509/*
510 * Receive (potentially fragmented) response from the card
511 */
512static int gpc_iso_recv_frag(ifd_reader_t * reader, unsigned char cmd,
513                             const unsigned char *data, size_t data_len,
514                             ct_buf_t * bp)
515{
516        static unsigned char more_data[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
517        unsigned char buffer[256];
518        int rc, status;
519
520        if (!data) {
521                data = more_data;
522                data_len = sizeof(more_data);
523        } else if (data_len > sizeof(buffer) - 1) {
524                return IFD_ERROR_BUFFER_TOO_SMALL;
525        }
526
527        buffer[0] = cmd;
528        memcpy(buffer + 1, data, data_len);
529
530        rc = __gpc_command(reader, buffer, 1 + data_len,
531                           buffer, sizeof(buffer), &status);
532        if (rc < 0)
533                return rc;
534
535        ct_buf_put(bp, buffer, rc);
536        if (status != 0x00      /* success */
537            && status != 0xE7   /* not 9000 */
538            && status != 0xE5   /* not 9000 */
539            && status != 0x1B) {        /* more data */
540                ct_error("error 0x%02x in ISO OUPUT/EXCHANGE APDU (%s)",
541                         status, gpc_strerror(status));
542                return IFD_ERROR_COMM_ERROR;
543        }
544
545        /* so exchange/send stop looping. is 1b right here? */
546        if (status != 0x00 && status != 0x1B)
547                return 0;
548
549        return rc;
550}
551
552/*
553 * Send case 2 APDU to card, receive lots of data in response.
554 * Due to the limitations imposed by GBP, the reader may have
555 * to send the response fragmented into several parts.
556 */
557static int gpc_iso_output(ifd_reader_t * reader, const unsigned char *cmd_buf,
558                          size_t cmd_len, unsigned char *res_buf,
559                          size_t res_len)
560{
561        ct_buf_t res;
562        size_t expect = 0;
563        int rc;
564
565        ct_buf_init(&res, res_buf, res_len);
566        if (cmd_len > 4) {
567                expect = cmd_buf[4];
568                if (expect == 0)
569                        expect = 256;
570                expect += 2;    /* for status word */
571                if (expect > res_len)
572                        expect = res_len;
573        }
574
575        while (1) {
576                rc = gpc_iso_recv_frag(reader, 0x13, cmd_buf, cmd_len, &res);
577                if (rc <= 0 || ct_buf_avail(&res) >= expect)
578                        break;
579
580                cmd_buf = NULL;
581                cmd_len = 0;
582        }
583
584        if (rc < 0)
585                return rc;
586        return ct_buf_avail(&res);
587}
588
589/*
590 * Send APDU+data to card
591 */
592static int gpc_iso_input(ifd_reader_t * reader, const unsigned char *cmd_buf,
593                         size_t cmd_len, unsigned char *res_buf, size_t res_len)
594{
595        unsigned char buffer[GPC_ISO_INPUT_MAX + 1];
596        int rc;
597
598        if (cmd_len > GPC_ISO_INPUT_MAX) {
599                size_t chunk = cmd_len - GPC_ISO_INPUT_MAX;
600
601                rc = gpc_iso_send_frag(reader, 0x14, cmd_buf + chunk, chunk);
602                if (rc < 0)
603                        return rc;
604                cmd_len = GPC_ISO_INPUT_MAX;
605        }
606
607        buffer[0] = 0x14;
608        memcpy(buffer + 1, cmd_buf, cmd_len);
609
610        if (cmd_len == 4)
611                buffer[++cmd_len] = 0x00;
612
613        return gpc_command(reader, buffer, cmd_len + 1, res_buf, 2);
614}
615
616static int gpc_iso_exchange_apdu(ifd_reader_t * reader,
617                                 const unsigned char *cmd_buf, size_t cmd_len,
618                                 unsigned char *res_buf, size_t res_len)
619{
620        ct_buf_t res;
621        size_t expect = 0;
622        int rc;
623
624        ct_buf_init(&res, res_buf, res_len);
625        if (cmd_len > 4) {
626                expect = cmd_buf[4];
627                if (expect == 0)
628                        expect = 256;
629                expect += 2;    /* for status word */
630                if (expect > res_len)
631                        expect = res_len;
632        }
633
634        if (cmd_len > GPC_ISO_EXCHANGE_MAX) {
635                size_t chunk = cmd_len - GPC_ISO_EXCHANGE_MAX;
636
637                rc = gpc_iso_send_frag(reader, 0x15, cmd_buf + chunk, chunk);
638                if (rc < 0)
639                        return rc;
640                cmd_len = GPC_ISO_EXCHANGE_MAX;
641        }
642
643        while (1) {
644                rc = gpc_iso_recv_frag(reader, 0x15, cmd_buf, cmd_len, &res);
645                if (rc <= 0 || ct_buf_avail(&res) >= expect)
646                        break;
647
648                /* Added by Chaskiel - I don't understand why */
649                if (ct_buf_avail(&res) == 2 && expect == 258)
650                        break;
651
652                cmd_buf = NULL;
653                cmd_len = 0;
654        }
655
656        if (rc < 0)
657                return rc;
658        return ct_buf_avail(&res);
659}
660
661/*
662 * Get the OS version
663 */
664static int gpc_get_os_version(ifd_reader_t * reader, char *buf, size_t len)
665{
666        static unsigned char cmd[] = { 0x22, 0x05, 0x3F, 0xE0, 0x10 };
667
668        /* Ensure NUL termination */
669        memset(buf, 0, len);
670        return gpc_command(reader, cmd, sizeof(cmd), buf, len - 1);
671}
672
673/*
674 * Helper functions
675 */
676static int __gpc_command(ifd_reader_t * reader, const void *cmd,
677                         size_t cmd_len, void *res, size_t res_len,
678                         int *gpc_status)
679{
680        gpc_status_t *st = (gpc_status_t *) reader->driver_data;
681        unsigned char buffer[257];
682        size_t len;
683        int rc;
684
685        if (res_len > sizeof(buffer) - 1)
686                return IFD_ERROR_GENERIC;
687
688        if (st->p == NULL) {
689                ct_error("No host-reader comm protocol selected\n");
690                return IFD_ERROR_GENERIC;
691        }
692
693        if (ct_config.debug >= 3)
694                ifd_debug(3, "sending:%s", ct_hexdump(cmd, cmd_len));
695
696        rc = ifd_protocol_transceive(st->p, 0,
697                                     cmd, cmd_len, buffer, sizeof(buffer));
698        if (rc < 0)
699                return rc;
700        if (rc == 0) {
701                ct_error("zero length response from reader?!\n");
702                return IFD_ERROR_GENERIC;
703        }
704
705        if (ct_config.debug >= 3)
706                ifd_debug(3, "received:%s", ct_hexdump(buffer, rc));
707
708        len = rc - 1;
709        if (buffer[0] != 0x00) {
710                ifd_debug(2, "reader reports status 0x%02x (%s)\n",
711                          buffer[0], gpc_strerror(buffer[0]));
712        }
713        if (gpc_status)
714                *gpc_status = buffer[0];
715
716        if (len > res_len)
717                len = res_len;
718        if (len && res)
719                memcpy(res, buffer + 1, len);
720        return len;
721}
722
723static int gpc_command(ifd_reader_t * reader, const void *cmd, size_t cmd_len,
724                       void *res, size_t res_len)
725{
726        int rc, status;
727
728        rc = __gpc_command(reader, cmd, cmd_len, res, res_len, &status);
729        if (rc >= 0 && status == 0x01)
730                rc = IFD_ERROR_NOT_SUPPORTED;
731        if (rc >= 0 && status != 0x00 && status != 0xE5 && status != 0xE7)
732                rc = IFD_ERROR_COMM_ERROR;
733        return rc;
734}
735
736/*
737 * GPC error handling
738 */
739static const char *gpc_strerror(int status)
740{
741        switch (status) {
742        case 0x00:
743                return "Success";
744        case 0x01:
745                return "Unknown GemCore command";
746        case 0x02:
747                return "Operation impossible with this driver";
748        case 0x03:
749                return "Incorrect number of arguments";
750        case 0x10:
751                return "The first byte of the response (TS) is not valid";
752        case 0x1b:
753                return "More data available";
754        case 0x1d:
755                return "Wrong ATR TCK";
756        case 0xa0:
757                return "Error in card reset response";
758        case 0xa1:
759                return "Card protocol error";
760        case 0xa2:
761                return "Card is mute";
762        case 0xa3:
763                return "Parity error during exchange";
764        case 0xa4:
765                return "Card has aborted chaining (T=1)";
766        case 0xa5:
767                return "Reader has aborted chaining (T=1)";
768        case 0xa6:
769                return "RESYNCH successfully performed by GemCore";
770        case 0xa7:
771                return "Protocol Type Selection (PTS) error";
772        case 0xa8:
773                return "Card and reader in EMV mode";
774        case 0xe5:
775                return "Card interrupted the exchange after SW1";
776        case 0xe7:
777                return "\"Error\" returned by the card (SW is not 9000)";
778        case 0xf7:
779                return "Card removed during execution of a command";
780        case 0xfb:
781                return "Card missing";
782        }
783        return "Unknown error";
784}
785
786/*
787 * Driver operations
788 */
789static struct ifd_driver_ops gempc_driver;
790
791void ifd_gempc_register(void)
792{
793        gempc_driver.open = gpc_open;
794        gempc_driver.close = gpc_close;
795        gempc_driver.activate = gpc_activate;
796        gempc_driver.deactivate = gpc_deactivate;
797        gempc_driver.set_protocol = gpc_set_protocol;
798        gempc_driver.card_status = gpc_card_status;
799        gempc_driver.card_reset = gpc_card_reset;
800        gempc_driver.transparent = gpc_transparent;
801        ifd_driver_register("gempc", &gempc_driver);
802}
Note: See TracBrowser for help on using the repository browser.