source: branches/smartreader/csctapi/icc_async.c@ 1255

Last change on this file since 1255 was 1255, checked in by rorothetroll, 13 years ago

resync with trunk

File size: 11.3 KB
Line 
1/*
2 icc_async.c
3 Asynchronous ICC's handling functions
4
5 This file is part of the Unix driver for Towitoko smartcard readers
6 Copyright (C) 2000 2001 Carlos Prados <cprados@yahoo.com>
7
8 This version is modified by doz21 to work in a special manner ;)
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#include "defines.h"
26#include "../globals.h"
27#include "icc_async.h"
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include "ifd.h"
32
33/*
34 * Not exported constants definition
35 */
36#define ICC_ASYNC_MAX_TRANSMIT 255
37#define ICC_ASYNC_BAUDRATE 9600
38
39/*
40 * Not exported functions declaration
41 */
42
43static void ICC_Async_InvertBuffer (unsigned size, BYTE * buffer);
44static void ICC_Async_Clear (ICC_Async * icc);
45
46int fdmc=(-1);
47
48/*
49 * Exported functions definition
50 */
51
52ICC_Async *ICC_Async_New (void)
53{
54 ICC_Async *icc;
55
56 /* Allocate memory */
57 icc = (ICC_Async *) malloc (sizeof (ICC_Async));
58
59 if (icc != NULL)
60 ICC_Async_Clear (icc);
61
62 return icc;
63}
64
65int ICC_Async_Device_Init ()
66{
67
68 wr = 0;
69#ifdef DEBUG_IO
70 printf ("IO: Opening serial port %s\n", reader[ridx].device);
71#endif
72
73#if defined(SCI_DEV) || defined(COOL)
74 if (reader[ridx].typ == R_INTERNAL)
75#ifdef SH4
76 reader[ridx].handle = open (reader[ridx].device, O_RDWR|O_NONBLOCK|O_NOCTTY);
77#elif COOL
78 return Cool_Init();
79#else
80 reader[ridx].handle = open (reader[ridx].device, O_RDWR);
81#endif
82 else
83#endif
84
85 reader[ridx].handle = open (reader[ridx].device, O_RDWR | O_NOCTTY| O_NONBLOCK);
86
87 if (reader[ridx].handle < 0)
88 return ICC_ASYNC_IFD_ERROR;
89
90#if defined(TUXBOX) && defined(PPC)
91 if ((reader[ridx].typ == R_DB2COM1) || (reader[ridx].typ == R_DB2COM2))
92 if ((fdmc = open(DEV_MULTICAM, O_RDWR)) < 0)
93 {
94 close(reader[ridx].handle);
95 return ICC_ASYNC_IFD_ERROR;
96 }
97#endif
98
99 if (reader[ridx].typ != R_INTERNAL) { //FIXME move to ifd_phoenix.c
100 if(!IO_Serial_InitPnP ())
101 return ICC_ASYNC_IFD_ERROR;
102 IO_Serial_Flush();
103 }
104
105 return ICC_ASYNC_OK;
106}
107
108int ICC_Async_GetStatus (BYTE * result)
109{
110 BYTE status[2];
111// unsigned int modembits=0;
112 int in;
113
114// printf("\n%08X\n", (int)ifd->io);
115
116// status : 0 -start, 1 - card, 2- no card
117
118#ifdef SCI_DEV
119 if(reader[ridx].typ == R_INTERNAL)
120 {
121 if(!Sci_GetStatus(reader[ridx].handle, &in))
122 return IFD_TOWITOKO_IO_ERROR;
123 }
124 else
125#elif COOL
126 if(reader[ridx].typ == R_INTERNAL)
127 {
128 if (!Cool_GetStatus(&in))
129 return IFD_TOWITOKO_IO_ERROR;
130 }
131 else
132#endif
133
134#if defined(TUXBOX) && defined(PPC)
135 if ((reader[ridx].typ == R_DB2COM1) || (reader[ridx].typ == R_DB2COM2))
136 {
137 ushort msr=1;
138 extern int fdmc;
139 IO_Serial_Ioctl_Lock(1);
140 ioctl(fdmc, GET_PCDAT, &msr);
141 if (reader[ridx].typ == R_DB2COM2)
142 in=(!(msr & 1));
143 else
144 in=((msr & 0x0f00) == 0x0f00);
145 IO_Serial_Ioctl_Lock(0);
146 }
147 else
148#endif
149#ifdef USE_GPIO
150 if (gpio_detect)
151 in=get_gpio();
152 else
153#endif
154 if (!Phoenix_GetStatus(&in))
155 return IFD_TOWITOKO_IO_ERROR;
156
157 if (in)
158 {
159 if(reader[ridx].status == 0)
160 {
161 status[0] = IFD_TOWITOKO_CARD_CHANGE;
162 reader[ridx].status = 1;
163#ifdef USE_GPIO
164 if (gpio_detect) set_gpio1(0);
165#endif
166 }
167 else if(reader[ridx].status == 1)
168 {
169 status[0] = IFD_TOWITOKO_CARD_NOCHANGE;
170 }
171 else
172 {
173 status[0] = IFD_TOWITOKO_CARD_CHANGE;
174 reader[ridx].status = 1;
175#ifdef USE_GPIO
176 if (gpio_detect) set_gpio1(0);
177#endif
178 }
179 }
180 else
181 {
182 if(reader[ridx].status == 0)
183 {
184 status[0] = IFD_TOWITOKO_NOCARD_CHANGE;
185 reader[ridx].status = 2;
186#ifdef USE_GPIO
187 if (gpio_detect) set_gpio1(1);
188#endif
189 }
190 else if(reader[ridx].status == 1)
191 {
192 status[0] = IFD_TOWITOKO_NOCARD_CHANGE;
193 reader[ridx].status = 2;
194#ifdef USE_GPIO
195 if (gpio_detect) set_gpio1(1);
196#endif
197 }
198 else
199 {
200 status[0] = IFD_TOWITOKO_NOCARD_NOCHANGE;
201 }
202 }
203
204
205 (*result) = status[0];
206
207#ifdef DEBUG_IFD
208 printf ("IFD: com%d Status = %s / %s\n", reader[ridx].typ, IFD_TOWITOKO_CARD(status[0])? "card": "no card", IFD_TOWITOKO_CHANGE(status[0])? "change": "no change");
209#endif
210
211 return IFD_TOWITOKO_OK;
212}
213
214int ICC_Async_Init (ICC_Async * icc, IFD * ifd)
215{
216#ifndef ICC_TYPE_SYNC
217 unsigned np=0;
218
219 /* Initialize Baudrate */
220 if (!Phoenix_SetBaudrate (ICC_ASYNC_BAUDRATE))
221 return ICC_ASYNC_IFD_ERROR;
222
223 /* Activate ICC */
224 if (IFD_Towitoko_ActivateICC (ifd) != IFD_TOWITOKO_OK)
225 return ICC_ASYNC_IFD_ERROR;
226 /* Reset ICC */
227#ifdef SCI_DEV
228 if (reader[ridx].typ == R_INTERNAL) {
229 if (!Sci_Reset(&(icc->atr)))
230 {
231 icc->atr = NULL;
232 return ICC_ASYNC_IFD_ERROR;
233 }
234 }
235 else
236#endif
237#ifdef COOL
238 if (reader[ridx].typ == R_INTERNAL) {
239 if (!Cool_Reset(&(icc->atr)))
240 {
241 icc->atr = NULL;
242 return ICC_ASYNC_IFD_ERROR;
243 }
244 }
245 else
246#endif
247 if (!Phoenix_Reset(&(icc->atr)))
248 {
249 icc->atr = NULL;
250 return ICC_ASYNC_IFD_ERROR;
251 }
252 /* Get ICC convention */
253 if (ATR_GetConvention (icc->atr, &(icc->convention)) != ATR_OK)
254 {
255 ATR_Delete (icc->atr);
256 icc->atr = NULL;
257 icc->convention = 0;
258
259 return ICC_ASYNC_ATR_ERROR;
260 }
261
262 icc->protocol_type = ATR_PROTOCOL_TYPE_T0;
263
264 ATR_GetNumberOfProtocols (icc->atr, &np);
265
266 /*
267 * Get protocol offered by interface bytes T*2 if available,
268 * (that is, if TD1 is available), * otherwise use default T=0
269 */
270/* if (np>1)
271 ATR_GetProtocolType (icc->atr, 1, &(icc->protocol_type));
272
273#ifdef DEBUG_ICC
274 printf("ICC: Detected %s convention processor card T=%d\n",(icc->convention == ATR_CONVENTION_DIRECT ? "direct" : "inverse"), icc->protocol_type);
275#endif
276 *///really should let PPS handle this
277
278 /* Initialize member variables */
279 icc->baudrate = ICC_ASYNC_BAUDRATE;
280 icc->ifd = ifd;
281
282 if (icc->convention == ATR_CONVENTION_INVERSE)
283 {
284 if (!IO_Serial_SetParity (PARITY_ODD))
285 return ICC_ASYNC_IFD_ERROR;
286 }
287 else if(icc->protocol_type == ATR_PROTOCOL_TYPE_T14)
288 {
289 if (!IO_Serial_SetParity (PARITY_NONE))
290 return ICC_ASYNC_IFD_ERROR;
291 }
292 else
293 {
294 if (!IO_Serial_SetParity (PARITY_EVEN))
295 return ICC_ASYNC_IFD_ERROR;
296 }
297#ifdef COOL
298 if (reader[ridx].typ != R_INTERNAL)
299#endif
300 IO_Serial_Flush();
301 return ICC_ASYNC_OK;
302#else
303 return ICC_ASYNC_ATR_ERROR;
304#endif
305}
306
307int ICC_Async_SetTimings (ICC_Async * icc, ICC_Async_Timings * timings)
308{
309 icc->timings.block_delay = timings->block_delay;
310 icc->timings.char_delay = timings->char_delay;
311 icc->timings.block_timeout = timings->block_timeout;
312 icc->timings.char_timeout = timings->char_timeout;
313/* if (icc->protocol_type == ATR_PROTOCOL_TYPE_T1)
314 cs_debug("SetTimings: T1: chardelay %d, chartimeout CWT %d, blockdelay BGT??? %d, blocktimeout BWT %d",timings->char_delay,timings->char_timeout, timings->block_delay, timings->block_timeout);
315 else
316 cs_debug("SetTimings: T0/T14: chardelay %d, chartimeout WWT %d, blockdelay %d, blocktimeout %d",timings->char_delay,timings->char_timeout, timings->block_delay, timings->block_timeout);*/
317
318#ifdef SCI_DEV
319#include <sys/ioctl.h>
320#include "sci_global.h"
321#include "sci_ioctl.h"
322 if (reader[ridx].typ == R_INTERNAL) {
323 SCI_PARAMETERS params;
324 if (ioctl(reader[ridx].handle, IOCTL_GET_PARAMETERS, &params) < 0 )
325 return ICC_ASYNC_IFD_ERROR;
326 switch (icc->protocol_type) {
327 case ATR_PROTOCOL_TYPE_T1:
328 params.BWT = icc->timings.block_timeout;
329 params.CWT = icc->timings.char_timeout;
330 //params.BGT = icc->timings.block_delay; load into params.EGT??
331 break;
332 case ATR_PROTOCOL_TYPE_T0:
333 case ATR_PROTOCOL_TYPE_T14:
334 default:
335 params.WWT = icc->timings.char_timeout;
336 break;
337 }
338 if (ioctl(reader[ridx].handle, IOCTL_SET_PARAMETERS, &params)!=0)
339 return ICC_ASYNC_IFD_ERROR;
340
341 cs_debug("Set Timings: T=%d fs=%lu ETU=%d WWT=%d CWT=%d BWT=%d EGT=%d clock=%d check=%d P=%d I=%d U=%d", (int)params.T, params.fs, (int)params.ETU, (int)params.WWT, (int)params.CWT, (int)params.BWT, (int)params.EGT, (int)params.clock_stop_polarity, (int)params.check, (int)params.P, (int)params.I, (int)params.U);
342 }
343#endif
344 return ICC_ASYNC_OK;
345}
346
347int ICC_Async_GetTimings (ICC_Async * icc, ICC_Async_Timings * timings)
348{
349 timings->block_delay = icc->timings.block_delay;
350 timings->char_delay = icc->timings.char_delay;
351 timings->block_timeout = icc->timings.block_timeout;
352 timings->char_timeout = icc->timings.char_timeout;
353
354 return ICC_ASYNC_OK;
355}
356
357int ICC_Async_SetBaudrate (ICC_Async * icc, unsigned long baudrate)
358{
359 icc->baudrate = baudrate;
360 if (!Phoenix_SetBaudrate (baudrate))
361 return ICC_ASYNC_IFD_ERROR;
362
363 return ICC_ASYNC_OK;
364}
365
366int ICC_Async_GetBaudrate (ICC_Async * icc, unsigned long * baudrate)
367{
368 (*baudrate) = icc->baudrate;
369 return ICC_ASYNC_OK;
370}
371
372int ICC_Async_Transmit (ICC_Async * icc, unsigned size, BYTE * data)
373{
374 BYTE *buffer = NULL, *sent;
375 IFD_Timings timings;
376
377 if (icc->convention == ATR_CONVENTION_INVERSE && reader[ridx].typ != R_INTERNAL)
378 {
379 buffer = (BYTE *) calloc(sizeof (BYTE), size);
380 memcpy (buffer, data, size);
381 ICC_Async_InvertBuffer (size, buffer);
382 sent = buffer;
383 }
384 else
385 {
386 sent = data;
387 }
388
389 timings.block_delay = icc->timings.block_delay;
390 timings.char_delay = icc->timings.char_delay;
391
392#ifdef COOL
393 if (reader[ridx].typ == R_INTERNAL) {
394 if (!Cool_Transmit(sent, size))
395 return ICC_ASYNC_IFD_ERROR;
396 }
397 else
398#endif
399 if (!Phoenix_Transmit (sent, size, &timings, size))
400 return ICC_ASYNC_IFD_ERROR;
401
402 if (icc->convention == ATR_CONVENTION_INVERSE)
403 free (buffer);
404
405 return ICC_ASYNC_OK;
406}
407
408int ICC_Async_Receive (ICC_Async * icc, unsigned size, BYTE * data)
409{
410 IFD_Timings timings;
411
412 timings.block_timeout = icc->timings.block_timeout;
413 timings.char_timeout = icc->timings.char_timeout;
414
415#ifdef COOL
416 if (reader[ridx].typ == R_INTERNAL) {
417 if (!Cool_Receive(data, size))
418 return ICC_ASYNC_IFD_ERROR;
419 }
420 else
421#else
422 if (!Phoenix_Receive (data, size, &timings))
423 return ICC_ASYNC_IFD_ERROR;
424#endif
425
426 if (icc->convention == ATR_CONVENTION_INVERSE && reader[ridx].typ != R_INTERNAL)
427 ICC_Async_InvertBuffer (size, data);
428
429 return ICC_ASYNC_OK;
430}
431
432ATR * ICC_Async_GetAtr (ICC_Async * icc)
433{
434 return icc->atr;
435}
436
437IFD * ICC_Async_GetIFD (ICC_Async * icc)
438{
439 return icc->ifd;
440}
441
442int ICC_Async_Close (ICC_Async * icc)
443{
444 /* Dectivate ICC */
445 if (IFD_Towitoko_DeactivateICC (icc->ifd) != IFD_TOWITOKO_OK)
446 return ICC_ASYNC_IFD_ERROR;
447
448 /* Delete atr */
449 ATR_Delete (icc->atr);
450
451 ICC_Async_Clear (icc);
452
453 return ICC_ASYNC_OK;
454}
455
456unsigned long ICC_Async_GetClockRate ()
457{
458 switch (reader[ridx].cardmhz) {
459 case 357:
460 case 358:
461 return (372L * 9600L);
462 case 368:
463 return (384L * 9600L);
464 default:
465 return reader[ridx].cardmhz * 10000L;
466 }
467}
468
469void ICC_Async_Delete (ICC_Async * icc)
470{
471 free (icc);
472}
473
474/*
475 * Not exported functions definition
476 */
477
478static void ICC_Async_InvertBuffer (unsigned size, BYTE * buffer)
479{
480 uint i;
481
482 for (i = 0; i < size; i++)
483 buffer[i] = ~(INVERT_BYTE (buffer[i]));
484}
485
486static void ICC_Async_Clear (ICC_Async * icc)
487{
488 icc->ifd = NULL;
489 icc->atr = NULL;
490 icc->baudrate = 0L;
491 icc->convention = 0;
492 icc->protocol_type = -1;
493 icc->timings.block_delay = 0;
494 icc->timings.char_delay = 0;
495 icc->timings.block_timeout = 0;
496 icc->timings.char_timeout = 0;
497}
Note: See TracBrowser for help on using the repository browser.