source: trunk/src/ifd/ifd-epass3k.c @ 1185

Revision 1185, 7.6 KB checked in by aj, 2 years ago (diff)

Xiaoshuo Wu/Entersafe?:
make ePass3000 USB key work with OpenCT. We found out that new ePass3000
hardware returns data instead of 61XX(to indicates the number of response
bytes still available), so we modified OpenCT to handle it.

Line 
1/*
2 * OpenCT driver for ePass3000 device
3 *
4 * Copyright (C) 2008, EnterSafe <dev@entersafe.com>
5 */
6
7#include "internal.h"
8#include <stdlib.h>
9#include <string.h>
10
11typedef struct {
12        unsigned char TagH;
13        unsigned char TagL;
14        unsigned char CommandH;
15        unsigned char CommandL;
16        unsigned char LengthH;
17        unsigned char LengthL;
18        unsigned char Value[1];
19} epass3k_command_t;
20
21typedef struct {
22        unsigned char TagH;
23        unsigned char TagL;
24        unsigned char StatusH;
25        unsigned char StatusL;
26        unsigned char LengthH;
27        unsigned char LengthL;
28        unsigned char Value[1];
29} epass3k_status_t;
30
31#define TIMEOUT                         200000
32#define USB_BULK_IN                     0x81
33#define USB_BULK_OUT                    2
34#define EPASS3K_COMMAND_SIZE            7
35#define EPASS3K_STATUS_SIZE             7
36#define TOKEN_TYPE_ID_LENGTH            64
37#define EPASS3K_COMMAND_GET_ATR         (unsigned char)0X01
38#define EPASS3K_COMMAND_TRANSMIT_APDU   (unsigned char)0X02
39
40/*
41 * Initialize the device
42 */
43static int epass3k_open(ifd_reader_t * reader, const char *device_name)
44{
45        ifd_device_t *dev;
46        ifd_device_params_t params;
47        ifd_debug(1, "%s:%d epass3k_open()", __FILE__, __LINE__);
48
49        reader->name = "FT SCR2000A";   /* ePass3000 reader name */
50        reader->nslots = 1;
51        if (!(dev = ifd_device_open(device_name)))
52                return -1;
53
54        if (ifd_device_type(dev) != IFD_DEVICE_TYPE_USB) {
55                ct_error("ePass3000: device %s is not a USB device",
56                         device_name);
57                ifd_device_close(dev);
58                return -1;
59        }
60
61        params = dev->settings;
62        params.usb.ep_o = USB_BULK_OUT;
63        params.usb.ep_i = USB_BULK_IN;
64        if (ifd_device_set_parameters(dev, &params) < 0) {
65                ct_error("ePass3000: setting parameters failed", device_name);
66                ifd_device_close(dev);
67                return -1;
68        }
69
70        reader->device = dev;
71        dev->timeout = TIMEOUT;
72
73        return 0;
74}
75
76static int epass3k_activate(ifd_reader_t * reader)
77{
78        ifd_debug(1, "%s:%d epass3k_activate()", __FILE__, __LINE__);
79        return 0;
80}
81
82static int epass3k_deactivate(ifd_reader_t * reader)
83{
84        ifd_debug(1, "%s:%d epass3k_deactivate()", __FILE__, __LINE__);
85        return -1;
86}
87
88static int epass3k_change_parity(ifd_reader_t * reader, int parity)
89{
90        ifd_debug(1, "%s:%d epass3k_change_parity()", __FILE__, __LINE__);
91        return 0;
92}
93
94static int epass3k_change_speed(ifd_reader_t * reader, unsigned int speed)
95{
96        ifd_debug(1, "%s:%d epass3k_change_speed()", __FILE__, __LINE__);
97        return 0;
98}
99
100static int epass3k_set_protocol(ifd_reader_t * reader, int nslot, int proto)
101{
102        ifd_debug(1, "%s:%d epass3k_set_protocol()", __FILE__, __LINE__);
103        ifd_protocol_t *protocol;
104        ifd_slot_t *slot;
105
106        if (IFD_PROTOCOL_T0 != proto)
107                return IFD_ERROR_NOT_SUPPORTED;
108
109        slot = &reader->slot[nslot];
110
111        slot->proto = ifd_protocol_new(proto, reader, slot->dad);
112        if (slot->proto == NULL) {
113                ct_error("acr: unable to create protocol");
114                return -1;
115        }
116        ifd_protocol_set_parameter(slot->proto, IFD_PROTOCOL_BLOCK_ORIENTED, 1);
117        return 1;
118}
119
120static int epass3k_card_reset(ifd_reader_t * reader, int slot, void *atr,
121                              size_t atr_len)
122{
123        int ret;
124        epass3k_command_t *pepass3k_send = NULL;
125        epass3k_status_t *pepass3k_receive = NULL;
126
127        ifd_debug(1, "%s:%d epass3k_card_reset()", __FILE__, __LINE__);
128        pepass3k_send = (epass3k_command_t *) malloc(EPASS3K_COMMAND_SIZE);
129        pepass3k_receive =
130            (epass3k_status_t *) malloc(EPASS3K_STATUS_SIZE +
131                                        TOKEN_TYPE_ID_LENGTH);
132        if ((NULL == pepass3k_send) || (NULL == pepass3k_receive)) {
133                return -1;
134        }
135
136        memset(pepass3k_send, 0, EPASS3K_COMMAND_SIZE);
137        pepass3k_send->TagH = 'R';
138        pepass3k_send->TagL = '6';
139        pepass3k_send->CommandH = 0x00;
140        pepass3k_send->CommandL = EPASS3K_COMMAND_GET_ATR;
141        pepass3k_send->LengthH = 0x00;
142        pepass3k_send->LengthL = 0x00;
143        ret =
144            ifd_device_send(reader->device, (unsigned char *)pepass3k_send,
145                            EPASS3K_COMMAND_SIZE - 1);
146        if (ret != EPASS3K_COMMAND_SIZE - 1) {
147                free(pepass3k_send);
148                pepass3k_send = NULL;
149                free(pepass3k_receive);
150                pepass3k_receive = NULL;
151                return -1;
152        }
153
154        memset(pepass3k_receive, 0, EPASS3K_STATUS_SIZE + TOKEN_TYPE_ID_LENGTH);
155        pepass3k_receive->TagH = 'R';
156        pepass3k_receive->TagL = '6';
157        pepass3k_receive->LengthH = 0x00;
158        pepass3k_receive->LengthL = 0x20;
159        ret =
160            ifd_device_recv(reader->device, (unsigned char *)pepass3k_receive,
161                            EPASS3K_STATUS_SIZE + TOKEN_TYPE_ID_LENGTH,
162                            TIMEOUT);
163        if (ret < EPASS3K_STATUS_SIZE) {
164                free(pepass3k_send);
165                pepass3k_send = NULL;
166                free(pepass3k_receive);
167                pepass3k_receive = NULL;
168                return -1;
169        }
170
171        if (atr_len <
172            pepass3k_receive->LengthH * 256 + pepass3k_receive->LengthL - 5) {
173                free(pepass3k_send);
174                pepass3k_send = NULL;
175                free(pepass3k_receive);
176                pepass3k_receive = NULL;
177                return -1;
178        }
179        if (NULL != atr) {
180                memcpy(atr, pepass3k_receive->Value + 2,
181                       pepass3k_receive->LengthH * 256 +
182                       pepass3k_receive->LengthL - 5);
183        }
184        ret = pepass3k_receive->LengthH * 256 + pepass3k_receive->LengthL - 5;
185
186        free(pepass3k_send);
187        pepass3k_send = NULL;
188        free(pepass3k_receive);
189        pepass3k_receive = NULL;
190
191        return ret;
192}
193
194static int epass3k_card_status(ifd_reader_t * reader, int slot, int *status)
195{
196        ifd_debug(1, "%s:%d epass3k_card_status()", __FILE__, __LINE__);
197        *status = IFD_CARD_PRESENT;
198        return 0;
199}
200
201static int epass3k_send(ifd_reader_t * reader, unsigned int dad,
202                        const unsigned char *buffer, size_t len)
203{
204        int ret = 0;
205        ifd_debug(1, "%s:%d epass3k_send()", __FILE__, __LINE__);
206
207        epass3k_command_t *pepass3k_send = NULL;
208        pepass3k_send =
209            (epass3k_command_t *) malloc(EPASS3K_COMMAND_SIZE + len);
210        if (NULL == pepass3k_send) {
211                return -1;
212        }
213        memset(pepass3k_send, 0, EPASS3K_COMMAND_SIZE + len);
214        pepass3k_send->TagH = 'R';
215        pepass3k_send->TagL = '6';
216        pepass3k_send->CommandH = 0x00;
217        pepass3k_send->CommandL = EPASS3K_COMMAND_TRANSMIT_APDU;
218        pepass3k_send->LengthH = len / 256;
219        pepass3k_send->LengthL = len % 256;
220        memcpy(pepass3k_send->Value, buffer, len);
221
222        ret =
223            ifd_device_send(reader->device, (unsigned char *)pepass3k_send,
224                            EPASS3K_COMMAND_SIZE + len - 1);
225
226        if (NULL != pepass3k_send) ;
227        {
228                free(pepass3k_send);
229                pepass3k_send = NULL;
230        }
231
232        if (ret != EPASS3K_COMMAND_SIZE + len - 1) {
233                return -1;
234        }
235        return 0;
236}
237
238static int epass3k_recv(ifd_reader_t * reader, unsigned int dad,
239                        unsigned char *buffer, size_t len, long timeout)
240{
241        int ret = 0;
242        ifd_debug(1, "%s:%d epass3k_recv()", __FILE__, __LINE__);
243        epass3k_status_t *pepass3k_receive = NULL;
244        pepass3k_receive =
245            (epass3k_status_t *) malloc(EPASS3K_STATUS_SIZE + len);
246        memset(pepass3k_receive, 0, EPASS3K_STATUS_SIZE + len);
247        if (NULL == pepass3k_receive) {
248                return -1;
249        }
250        memset(pepass3k_receive, 0, EPASS3K_STATUS_SIZE + len);
251        pepass3k_receive->TagH = 'R';
252        pepass3k_receive->TagL = '6';
253        pepass3k_receive->LengthH = len / 256;
254        pepass3k_receive->LengthL = len % 256;
255        ret =
256            ifd_device_recv(reader->device, (unsigned char *)pepass3k_receive,
257                            EPASS3K_STATUS_SIZE + len, TIMEOUT);
258
259        if (ret < EPASS3K_STATUS_SIZE) {
260                if (pepass3k_receive)
261                        free(pepass3k_receive);
262                return -1;
263        }
264        if ((NULL != buffer)
265            && (pepass3k_receive->LengthH * 256 + pepass3k_receive->LengthL <=
266                len)) {
267                memcpy(buffer, pepass3k_receive->Value,
268                       pepass3k_receive->LengthH * 256 +
269                       pepass3k_receive->LengthL);
270        }
271
272        ret = pepass3k_receive->LengthH * 256 + pepass3k_receive->LengthL;
273        if (pepass3k_receive)
274                free(pepass3k_receive);
275
276        return ret;
277}
278
279static struct ifd_driver_ops epass3k_driver;
280
281void ifd_epass3k_register(void)
282{
283        epass3k_driver.open = epass3k_open;
284        epass3k_driver.activate = epass3k_activate;
285        epass3k_driver.deactivate = epass3k_deactivate;
286        epass3k_driver.card_reset = epass3k_card_reset;
287        epass3k_driver.card_status = epass3k_card_status;
288        epass3k_driver.change_parity = epass3k_change_parity;
289        epass3k_driver.change_speed = epass3k_change_speed;
290        epass3k_driver.send = epass3k_send;
291        epass3k_driver.recv = epass3k_recv;
292        epass3k_driver.set_protocol = epass3k_set_protocol;
293        ifd_driver_register("ePass3000", &epass3k_driver);
294}
Note: See TracBrowser for help on using the repository browser.