source: trunk/csctapi/icc_async.c@ 1279

Last change on this file since 1279 was 1279, checked in by dingo35, 11 years ago

Remove ICC_Async dynamic data structure, cleanup some parameters in t0 and t1

File size: 9.7 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#include "mc_global.h"
33
34/*
35 * Not exported constants definition
36 */
37#define ICC_ASYNC_MAX_TRANSMIT 255
38#define ICC_ASYNC_BAUDRATE 9600
39
40/*
41 * Not exported functions declaration
42 */
43
44static void ICC_Async_InvertBuffer (unsigned size, BYTE * buffer);
45static void ICC_Async_Clear ();
46
47int fdmc=(-1);
48
49/*
50 * Exported functions definition
51 */
52
53int ICC_Async_Device_Init ()
54{
55
56 wr = 0;
57#ifdef DEBUG_IO
58 printf ("IO: Opening serial port %s\n", reader[ridx].device);
59#endif
60
61#if defined(SCI_DEV) || defined(COOL)
62 if (reader[ridx].typ == R_INTERNAL)
63#if defined(SH4) || defined(STB04SCI)
64 reader[ridx].handle = open (reader[ridx].device, O_RDWR|O_NONBLOCK|O_NOCTTY);
65#elif COOL
66 return Cool_Init();
67#else
68 reader[ridx].handle = open (reader[ridx].device, O_RDWR);
69#endif
70 else
71#endif
72
73 reader[ridx].handle = open (reader[ridx].device, O_RDWR | O_NOCTTY| O_NONBLOCK);
74
75 if (reader[ridx].handle < 0)
76 return ICC_ASYNC_IFD_ERROR;
77
78#if defined(TUXBOX) && defined(PPC)
79 if ((reader[ridx].typ == R_DB2COM1) || (reader[ridx].typ == R_DB2COM2))
80 if ((fdmc = open(DEV_MULTICAM, O_RDWR)) < 0)
81 {
82 close(reader[ridx].handle);
83 return ICC_ASYNC_IFD_ERROR;
84 }
85#endif
86
87 if (reader[ridx].typ != R_INTERNAL) { //FIXME move to ifd_phoenix.c
88 if(!IO_Serial_InitPnP ())
89 return ICC_ASYNC_IFD_ERROR;
90 IO_Serial_Flush();
91 }
92
93 return ICC_ASYNC_OK;
94}
95
96int ICC_Async_GetStatus (BYTE * result)
97{
98 BYTE status[2];
99// unsigned int modembits=0;
100 int in;
101
102// printf("\n%08X\n", (int)ifd->io);
103
104// status : 0 -start, 1 - card, 2- no card
105
106#ifdef SCI_DEV
107 if(reader[ridx].typ == R_INTERNAL)
108 {
109 if(!Sci_GetStatus(reader[ridx].handle, &in))
110 return ICC_ASYNC_IFD_ERROR;
111 }
112 else
113#elif COOL
114 if(reader[ridx].typ == R_INTERNAL)
115 {
116 if (!Cool_GetStatus(&in))
117 return ICC_ASYNC_IFD_ERROR;
118 }
119 else
120#endif
121
122#if defined(TUXBOX) && defined(PPC)
123 if ((reader[ridx].typ == R_DB2COM1) || (reader[ridx].typ == R_DB2COM2))
124 {
125 ushort msr=1;
126 extern int fdmc;
127 IO_Serial_Ioctl_Lock(1);
128 ioctl(fdmc, GET_PCDAT, &msr);
129 if (reader[ridx].typ == R_DB2COM2)
130 in=(!(msr & 1));
131 else
132 in=((msr & 0x0f00) == 0x0f00);
133 IO_Serial_Ioctl_Lock(0);
134 }
135 else
136#endif
137 if (!Phoenix_GetStatus(&in))
138 return ICC_ASYNC_IFD_ERROR;
139
140 if (in)
141 {
142 if(reader[ridx].status == 0)
143 {
144 status[0] = IFD_TOWITOKO_CARD_CHANGE;
145 reader[ridx].status = 1;
146 }
147 else if(reader[ridx].status == 1)
148 {
149 status[0] = IFD_TOWITOKO_CARD_NOCHANGE;
150 }
151 else
152 {
153 status[0] = IFD_TOWITOKO_CARD_CHANGE;
154 reader[ridx].status = 1;
155 }
156 }
157 else
158 {
159 if(reader[ridx].status == 0)
160 {
161 status[0] = IFD_TOWITOKO_NOCARD_CHANGE;
162 reader[ridx].status = 2;
163 }
164 else if(reader[ridx].status == 1)
165 {
166 status[0] = IFD_TOWITOKO_NOCARD_CHANGE;
167 reader[ridx].status = 2;
168 }
169 else
170 {
171 status[0] = IFD_TOWITOKO_NOCARD_NOCHANGE;
172 }
173 }
174
175
176 (*result) = status[0];
177
178#ifdef DEBUG_IFD
179 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");
180#endif
181
182 return ICC_ASYNC_OK;
183}
184
185int ICC_Async_Init ()
186{
187#ifndef ICC_TYPE_SYNC
188 unsigned np=0;
189
190 /* Initialize Baudrate */
191 if (!Phoenix_SetBaudrate (ICC_ASYNC_BAUDRATE))
192 return ICC_ASYNC_IFD_ERROR;
193
194#ifdef SCI_DEV
195 /* Activate ICC */
196 if (!Sci_Activate())
197 return ICC_ASYNC_IFD_ERROR;
198 /* Reset ICC */
199 if (reader[ridx].typ == R_INTERNAL) {
200 if (!Sci_Reset(&(atr)))
201 {
202 atr = NULL;
203 return ICC_ASYNC_IFD_ERROR;
204 }
205 }
206 else
207#endif
208#ifdef COOL
209 if (reader[ridx].typ == R_INTERNAL) {
210 if (!Cool_Reset(&(atr)))
211 {
212 atr = NULL;
213 return ICC_ASYNC_IFD_ERROR;
214 }
215 }
216 else
217#endif
218 if (!Phoenix_Reset(&(atr)))
219 {
220 atr = NULL;
221 return ICC_ASYNC_IFD_ERROR;
222 }
223 /* Get ICC convention */
224 if (ATR_GetConvention (atr, &(convention)) != ATR_OK)
225 {
226 ATR_Delete (atr);
227 atr = NULL;
228 convention = 0;
229
230 return ICC_ASYNC_ATR_ERROR;
231 }
232
233 protocol_type = ATR_PROTOCOL_TYPE_T0;
234
235 ATR_GetNumberOfProtocols (atr, &np);
236
237 /*
238 * Get protocol offered by interface bytes T*2 if available,
239 * (that is, if TD1 is available), * otherwise use default T=0
240 */
241/* if (np>1)
242 ATR_GetProtocolType (atr, 1, &(protocol_type));
243
244#ifdef DEBUG_ICC
245 printf("ICC: Detected %s convention processor card T=%d\n",(convention == ATR_CONVENTION_DIRECT ? "direct" : "inverse"), protocol_type);
246#endif
247 *///really should let PPS handle this
248
249 /* Initialize member variables */
250 if (convention == ATR_CONVENTION_INVERSE)
251 {
252 if (!IO_Serial_SetParity (PARITY_ODD))
253 return ICC_ASYNC_IFD_ERROR;
254 }
255 else if(protocol_type == ATR_PROTOCOL_TYPE_T14)
256 {
257 if (!IO_Serial_SetParity (PARITY_NONE))
258 return ICC_ASYNC_IFD_ERROR;
259 }
260 else
261 {
262 if (!IO_Serial_SetParity (PARITY_EVEN))
263 return ICC_ASYNC_IFD_ERROR;
264 }
265#ifdef COOL
266 if (reader[ridx].typ != R_INTERNAL)
267#endif
268 IO_Serial_Flush();
269 return ICC_ASYNC_OK;
270#else
271 return ICC_ASYNC_ATR_ERROR;
272#endif
273}
274
275int ICC_Async_SetTimings ()
276{
277/* if (protocol_type == ATR_PROTOCOL_TYPE_T1)
278 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);
279 else
280 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);*/
281
282#ifdef SCI_DEV
283#include <sys/ioctl.h>
284#include "sci_global.h"
285#include "sci_ioctl.h"
286 if (reader[ridx].typ == R_INTERNAL) {
287 SCI_PARAMETERS params;
288 if (ioctl(reader[ridx].handle, IOCTL_GET_PARAMETERS, &params) < 0 )
289 return ICC_ASYNC_IFD_ERROR;
290 switch (protocol_type) {
291 case ATR_PROTOCOL_TYPE_T1:
292 params.BWT = icc_timings.block_timeout;
293 params.CWT = icc_timings.char_timeout;
294 //params.BGT = icc_timings.block_delay; load into params.EGT??
295 break;
296 case ATR_PROTOCOL_TYPE_T0:
297 case ATR_PROTOCOL_TYPE_T14:
298 default:
299 params.WWT = icc_timings.char_timeout;
300 break;
301 }
302 if (ioctl(reader[ridx].handle, IOCTL_SET_PARAMETERS, &params)!=0)
303 return ICC_ASYNC_IFD_ERROR;
304
305 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);
306 }
307#endif
308 return ICC_ASYNC_OK;
309}
310
311int ICC_Async_SetBaudrate (unsigned long baudrate)
312{
313 if (!Phoenix_SetBaudrate (baudrate))
314 return ICC_ASYNC_IFD_ERROR;
315
316 return ICC_ASYNC_OK;
317}
318
319int ICC_Async_GetBaudrate (unsigned long * baudrate)
320{
321 (*baudrate) = reader[ridx].baudrate;
322 return ICC_ASYNC_OK;
323}
324
325int ICC_Async_Transmit (unsigned size, BYTE * data)
326{
327 BYTE *buffer = NULL, *sent;
328 IFD_Timings timings;
329
330 if (convention == ATR_CONVENTION_INVERSE && reader[ridx].typ != R_INTERNAL)
331 {
332 buffer = (BYTE *) calloc(sizeof (BYTE), size);
333 memcpy (buffer, data, size);
334 ICC_Async_InvertBuffer (size, buffer);
335 sent = buffer;
336 }
337 else
338 {
339 sent = data;
340 }
341
342 timings.block_delay = icc_timings.block_delay;
343 timings.char_delay = icc_timings.char_delay;
344
345#ifdef COOL
346 if (reader[ridx].typ == R_INTERNAL) {
347 if (!Cool_Transmit(sent, size))
348 return ICC_ASYNC_IFD_ERROR;
349 }
350 else
351#endif
352 if (!Phoenix_Transmit (sent, size, &timings, size))
353 return ICC_ASYNC_IFD_ERROR;
354
355 if (convention == ATR_CONVENTION_INVERSE)
356 free (buffer);
357
358 return ICC_ASYNC_OK;
359}
360
361int ICC_Async_Receive (unsigned size, BYTE * data)
362{
363 IFD_Timings timings;
364
365 timings.block_timeout = icc_timings.block_timeout;
366 timings.char_timeout = icc_timings.char_timeout;
367
368#ifdef COOL
369 if (reader[ridx].typ == R_INTERNAL) {
370 if (!Cool_Receive(data, size))
371 return ICC_ASYNC_IFD_ERROR;
372 }
373 else
374#else
375 if (!Phoenix_Receive (data, size, &timings))
376 return ICC_ASYNC_IFD_ERROR;
377#endif
378
379 if (convention == ATR_CONVENTION_INVERSE && reader[ridx].typ != R_INTERNAL)
380 ICC_Async_InvertBuffer (size, data);
381
382 return ICC_ASYNC_OK;
383}
384
385int ICC_Async_Close ()
386{
387#ifdef SCI_DEV
388 /* Dectivate ICC */
389 if (!Sci_Deactivate())
390 return ICC_ASYNC_IFD_ERROR;
391#endif
392
393 /* Delete atr */
394 ATR_Delete (atr);
395
396 ICC_Async_Clear ();
397
398 return ICC_ASYNC_OK;
399}
400
401unsigned long ICC_Async_GetClockRate ()
402{
403 switch (reader[ridx].cardmhz) {
404 case 357:
405 case 358:
406 return (372L * 9600L);
407 case 368:
408 return (384L * 9600L);
409 default:
410 return reader[ridx].cardmhz * 10000L;
411 }
412}
413
414/*
415 * Not exported functions definition
416 */
417
418static void ICC_Async_InvertBuffer (unsigned size, BYTE * buffer)
419{
420 uint i;
421
422 for (i = 0; i < size; i++)
423 buffer[i] = ~(INVERT_BYTE (buffer[i]));
424}
425
426static void ICC_Async_Clear ()
427{
428 atr = NULL;
429 convention = 0;
430 protocol_type = -1;
431 icc_timings.block_delay = 0;
432 icc_timings.char_delay = 0;
433 icc_timings.block_timeout = 0;
434 icc_timings.char_timeout = 0;
435}
Note: See TracBrowser for help on using the repository browser.