source: branches/monitor-improvement/csctapi/icc_async.c@ 1180

Last change on this file since 1180 was 1180, checked in by alno, 12 years ago

WebIf:

  • Merging revisions 1177-1179 of trunk
File size: 10.8 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
46/*
47 * Exported functions definition
48 */
49
50ICC_Async *ICC_Async_New (void)
51{
52 ICC_Async *icc;
53
54 /* Allocate memory */
55 icc = (ICC_Async *) malloc (sizeof (ICC_Async));
56
57 if (icc != NULL)
58 ICC_Async_Clear (icc);
59
60 return icc;
61}
62
63int ICC_Async_Init (ICC_Async * icc, IFD * ifd)
64{
65#ifndef ICC_TYPE_SYNC
66 unsigned np=0;
67
68 /* LED Red */
69 if (IFD_Towitoko_SetLED () != IFD_TOWITOKO_OK)
70 return ICC_ASYNC_IFD_ERROR;
71
72 /* Initialize Baudrate */
73 if (IFD_Towitoko_SetBaudrate (ifd, ICC_ASYNC_BAUDRATE)!= IFD_TOWITOKO_OK)
74 return ICC_ASYNC_IFD_ERROR;
75
76 /* Activate ICC */
77 if (IFD_Towitoko_ActivateICC (ifd) != IFD_TOWITOKO_OK)
78 return ICC_ASYNC_IFD_ERROR;
79 /* Reset ICC */
80 if (IFD_Towitoko_ResetAsyncICC (ifd, &(icc->atr)) != IFD_TOWITOKO_OK)
81 {
82 icc->atr = NULL;
83 return ICC_ASYNC_IFD_ERROR;
84 }
85
86 /* Get ICC convention */
87 if (ATR_GetConvention (icc->atr, &(icc->convention)) != ATR_OK)
88 {
89 ATR_Delete (icc->atr);
90 icc->atr = NULL;
91 icc->convention = 0;
92
93 return ICC_ASYNC_ATR_ERROR;
94 }
95
96 icc->protocol_type = ATR_PROTOCOL_TYPE_T0;
97
98 ATR_GetNumberOfProtocols (icc->atr, &np);
99
100 /*
101 * Get protocol offered by interface bytes T*2 if available,
102 * (that is, if TD1 is available), * otherwise use default T=0
103 */
104/* if (np>1)
105 ATR_GetProtocolType (icc->atr, 1, &(icc->protocol_type));
106
107#ifdef DEBUG_ICC
108 printf("ICC: Detected %s convention processor card T=%d\n",(icc->convention == ATR_CONVENTION_DIRECT ? "direct" : "inverse"), icc->protocol_type);
109#endif
110 *///really should let PPS handle this
111 /* LED Green */
112 if (IFD_Towitoko_SetLED () != IFD_TOWITOKO_OK)
113 {
114 ATR_Delete (icc->atr);
115 icc->atr = NULL;
116 icc->convention = 0;
117
118 return ICC_ASYNC_IFD_ERROR;
119 }
120
121 /* Initialize member variables */
122 icc->baudrate = ICC_ASYNC_BAUDRATE;
123 icc->ifd = ifd;
124
125#ifdef NO_PAR_SWITCH
126 if (icc->convention == ATR_CONVENTION_INVERSE)
127 {
128 if (IFD_Towitoko_SetParity (icc->ifd, IFD_TOWITOKO_PARITY_ODD) != IFD_TOWITOKO_OK)
129 return ICC_ASYNC_IFD_ERROR;
130 }
131 else if(icc->protocol_type == ATR_PROTOCOL_TYPE_T14)
132 {
133 if (IFD_Towitoko_SetParity (icc->ifd, IFD_TOWITOKO_PARITY_NONE) != IFD_TOWITOKO_OK)
134 return ICC_ASYNC_IFD_ERROR;
135 }
136 else
137 {
138 if (IFD_Towitoko_SetParity (icc->ifd, IFD_TOWITOKO_PARITY_EVEN) != IFD_TOWITOKO_OK)
139 return ICC_ASYNC_IFD_ERROR;
140 }
141#ifdef COOL
142 if (icc->ifd->io->com != RTYP_SCI)
143#endif
144 IO_Serial_Flush(ifd->io);
145#endif
146 return ICC_ASYNC_OK;
147#else
148 return ICC_ASYNC_ATR_ERROR;
149#endif
150}
151
152int ICC_Async_SetTimings (ICC_Async * icc, ICC_Async_Timings * timings)
153{
154 icc->timings.block_delay = timings->block_delay;
155 icc->timings.char_delay = timings->char_delay;
156 icc->timings.block_timeout = timings->block_timeout;
157 icc->timings.char_timeout = timings->char_timeout;
158/* if (icc->protocol_type == ATR_PROTOCOL_TYPE_T1)
159 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);
160 else
161 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);*/
162
163#ifdef SCI_DEV
164#include <sys/ioctl.h>
165#include "sci_global.h"
166#include "sci_ioctl.h"
167 if (icc->ifd->io->com == RTYP_SCI) {
168 SCI_PARAMETERS params;
169 if (ioctl(icc->ifd->io->fd, IOCTL_GET_PARAMETERS, &params) < 0 )
170 return ICC_ASYNC_IFD_ERROR;
171 switch (icc->protocol_type) {
172 case ATR_PROTOCOL_TYPE_T1:
173 params.BWT = icc->timings.block_timeout;
174 params.CWT = icc->timings.char_timeout;
175 //params.BGT = icc->timings.block_delay; load into params.EGT??
176 break;
177 case ATR_PROTOCOL_TYPE_T0:
178 case ATR_PROTOCOL_TYPE_T14:
179 default:
180 params.WWT = icc->timings.char_timeout;
181 break;
182 }
183 if (ioctl(icc->ifd->io->fd, IOCTL_SET_PARAMETERS, &params)!=0)
184 return ICC_ASYNC_IFD_ERROR;
185
186 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);
187 }
188#endif
189 return ICC_ASYNC_OK;
190}
191
192int ICC_Async_GetTimings (ICC_Async * icc, ICC_Async_Timings * timings)
193{
194 timings->block_delay = icc->timings.block_delay;
195 timings->char_delay = icc->timings.char_delay;
196 timings->block_timeout = icc->timings.block_timeout;
197 timings->char_timeout = icc->timings.char_timeout;
198
199 return ICC_ASYNC_OK;
200}
201
202int ICC_Async_SetBaudrate (ICC_Async * icc, unsigned long baudrate)
203{
204 icc->baudrate = baudrate;
205/*#ifdef COOL
206 if (icc->ifd->io->com==RTYP_SCI) {
207 typedef unsigned long u_int32;
208 u_int32 clk;
209 //clk = 357*10000; // MHZ
210 //clk = baudrate * 3570000L / 9600L;
211 clk = 500*10000;
212 if (cnxt_smc_set_clock_freq(icc->ifd->io->handle, clk))
213 return ICC_ASYNC_IFD_ERROR;
214 printf("set clock to %lu Hz\n", clk);
215 return ICC_ASYNC_OK;
216 }
217 else
218#endif*/
219 if (IFD_Towitoko_SetBaudrate (icc->ifd, baudrate) != IFD_TOWITOKO_OK)
220 return ICC_ASYNC_IFD_ERROR;
221
222 return ICC_ASYNC_OK;
223}
224
225int ICC_Async_GetBaudrate (ICC_Async * icc, unsigned long * baudrate)
226{
227 (*baudrate) = icc->baudrate;
228 return ICC_ASYNC_OK;
229}
230
231int ICC_Async_BeginTransmission (ICC_Async * icc)
232{
233 /* Setup parity for this ICC */
234#ifndef NO_PAR_SWITCH
235 if (icc->convention == ATR_CONVENTION_INVERSE)
236 {
237 if (IFD_Towitoko_SetParity (icc->ifd, IFD_TOWITOKO_PARITY_ODD) != IFD_TOWITOKO_OK)
238 return ICC_ASYNC_IFD_ERROR;
239 }
240 else if(icc->protocol_type == ATR_PROTOCOL_TYPE_T14)
241 {
242 if (IFD_Towitoko_SetParity (icc->ifd, IFD_TOWITOKO_PARITY_NONE) != IFD_TOWITOKO_OK)
243 return ICC_ASYNC_IFD_ERROR;
244 }
245 else
246 {
247 if (IFD_Towitoko_SetParity (icc->ifd, IFD_TOWITOKO_PARITY_EVEN) != IFD_TOWITOKO_OK)
248 return ICC_ASYNC_IFD_ERROR;
249 }
250
251 /* Setup baudrate for this ICC */
252/* if (IFD_Towitoko_SetBaudrate (icc->ifd, icc->baudrate)!= IFD_TOWITOKO_OK)
253 return ICC_ASYNC_IFD_ERROR;
254*/
255#endif
256 return ICC_ASYNC_OK;
257}
258
259#ifdef COOL
260extern unsigned char cardbuffer[255];
261extern int cardbuflen;
262#endif
263
264int ICC_Async_Transmit (ICC_Async * icc, unsigned size, BYTE * data)
265{
266 BYTE *buffer = NULL, *sent;
267 IFD_Timings timings;
268
269 if (icc->convention == ATR_CONVENTION_INVERSE && icc->ifd->io->com!=RTYP_SCI)
270 {
271 buffer = (BYTE *) calloc(sizeof (BYTE), size);
272 memcpy (buffer, data, size);
273 ICC_Async_InvertBuffer (size, buffer);
274 sent = buffer;
275 }
276 else
277 {
278 sent = data;
279 }
280
281 timings.block_delay = icc->timings.block_delay;
282 timings.char_delay = icc->timings.char_delay;
283
284#ifdef COOL
285//transmit buffer to SC and put answer in cardbuffer
286 if (icc->ifd->io->com == RTYP_SCI) {
287#define TIMEOUT 4000 //max 4294
288 cardbuflen = 256;//it needs to know max buffer size to respond?
289 if (cnxt_smc_read_write(handle, FALSE, sent, size, cardbuffer, &cardbuflen, TIMEOUT, 0))
290 return ICC_ASYNC_IFD_ERROR;
291
292#ifdef DEBUG_IFD
293 //usually done in IFD_Towitoko, for COOL do it here
294 printf ("COOLIFD: Transmit: ");
295 int i;
296 for (i = 0; i < size; i++)
297 printf ("%X ", sent[i]);
298 printf ("\n");
299#endif
300 }
301 else
302#else
303 if (IFD_Towitoko_Transmit (icc->ifd, &timings, size, sent) != IFD_TOWITOKO_OK)
304 return ICC_ASYNC_IFD_ERROR;
305#endif
306
307 if (icc->convention == ATR_CONVENTION_INVERSE)
308 free (buffer);
309
310 return ICC_ASYNC_OK;
311}
312
313int ICC_Async_Receive (ICC_Async * icc, unsigned size, BYTE * data)
314{
315 IFD_Timings timings;
316
317 timings.block_timeout = icc->timings.block_timeout;
318 timings.char_timeout = icc->timings.char_timeout;
319
320#ifdef COOL
321//receive buffer to SC
322 if (size > cardbuflen)
323 size = cardbuflen; //never read past end of buffer
324 memcpy(data,cardbuffer,size);
325 cardbuflen -= size;
326 memmove(cardbuffer,cardbuffer+size,cardbuflen);
327
328#ifdef DEBUG_IFD
329 int i;
330 printf ("COOLIFD: Receive: "); //I think
331 for (i = 0; i < size; i++)
332 printf ("%X ", data[i]);
333 printf ("\n");
334 fflush(stdout);
335#endif
336 return ICC_ASYNC_OK;
337#else
338 if (IFD_Towitoko_Receive (icc->ifd, &timings, size, data) != IFD_TOWITOKO_OK)
339 return ICC_ASYNC_IFD_ERROR;
340#endif
341
342 if (icc->convention == ATR_CONVENTION_INVERSE && icc->ifd->io->com!=RTYP_SCI)
343 ICC_Async_InvertBuffer (size, data);
344
345 return ICC_ASYNC_OK;
346}
347
348int ICC_Async_EndTransmission (ICC_Async * icc)
349{
350#ifndef NO_PAR_SWITCH
351 /* Restore parity */
352 if (IFD_Towitoko_SetParity (icc->ifd, IFD_TOWITOKO_PARITY_NONE) != IFD_TOWITOKO_OK)
353 return ICC_ASYNC_IFD_ERROR;
354#endif
355
356 return ICC_ASYNC_OK;
357}
358
359ATR * ICC_Async_GetAtr (ICC_Async * icc)
360{
361 return icc->atr;
362}
363
364IFD * ICC_Async_GetIFD (ICC_Async * icc)
365{
366 return icc->ifd;
367}
368
369int ICC_Async_Close (ICC_Async * icc)
370{
371 /* Dectivate ICC */
372 if (IFD_Towitoko_DeactivateICC (icc->ifd) != IFD_TOWITOKO_OK)
373 return ICC_ASYNC_IFD_ERROR;
374
375 /* LED Off */
376 if (IFD_Towitoko_SetLED () != IFD_TOWITOKO_OK)
377 return ICC_ASYNC_IFD_ERROR;
378
379 /* Delete atr */
380 ATR_Delete (icc->atr);
381
382 ICC_Async_Clear (icc);
383
384 return ICC_ASYNC_OK;
385}
386
387unsigned long ICC_Async_GetClockRate (ICC_Async * icc)
388{
389 switch (icc->ifd->io->cardmhz) {
390 case 357:
391 case 358:
392 return (372L * 9600L);
393 case 368:
394 return (384L * 9600L);
395 default:
396 return icc->ifd->io->cardmhz * 10000L;
397 }
398}
399
400void ICC_Async_Delete (ICC_Async * icc)
401{
402 free (icc);
403}
404
405/*
406 * Not exported functions definition
407 */
408
409static void ICC_Async_InvertBuffer (unsigned size, BYTE * buffer)
410{
411 uint i;
412
413 for (i = 0; i < size; i++)
414 buffer[i] = ~(INVERT_BYTE (buffer[i]));
415}
416
417static void ICC_Async_Clear (ICC_Async * icc)
418{
419 icc->ifd = NULL;
420 icc->atr = NULL;
421 icc->baudrate = 0L;
422 icc->convention = 0;
423 icc->protocol_type = -1;
424 icc->timings.block_delay = 0;
425 icc->timings.char_delay = 0;
426 icc->timings.block_timeout = 0;
427 icc->timings.char_timeout = 0;
428}
Note: See TracBrowser for help on using the repository browser.