source: trunk/csctapi/ifd_phoenix.c@ 2561

Last change on this file since 2561 was 2561, checked in by rorothetroll, 11 years ago

fix some reset delay before ATR. ISO docs gives timing for reset and when data can be transmited and minimum time is 46.2 ms, so I set the delay to 50ms after reset before we try to read the ATR

  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1/*
2 ifd_phoenix.c
3 This module provides IFD handling functions for Smartmouse/Phoenix reader.
4*/
5#include <stdio.h>
6//#include <time.h>
7//#include <string.h>
8//#include "ioctls.h"
9#include "../globals.h"
10#include "atr.h"
11#include <termios.h>
12#include "ifd_phoenix.h"
13#include "icc_async.h"
14#include "io_serial.h"
15
16#define MAX_TRANSMIT 255
17
18#ifdef USE_GPIO //felix: definition of gpio functions
19int gpio_outen,gpio_out,gpio_in;
20unsigned int pin,gpio;
21int gpio_detect=0;
22
23static void set_gpio(int level)
24{
25 read(gpio_outen, &gpio, sizeof(gpio));
26 gpio |= pin;
27 write(gpio_outen, &gpio, sizeof(gpio));
28
29 read(gpio_out, &gpio, sizeof(gpio));
30 if (level>0)
31 gpio|=pin;
32 else
33 gpio&=~pin;
34 write(gpio_out, &gpio, sizeof(gpio));
35}
36
37static void set_gpio_input(void)
38{
39 read(gpio_outen, &gpio, sizeof(gpio));
40 gpio &= ~pin;
41 write(gpio_outen, &gpio, sizeof(gpio));
42}
43
44static int get_gpio(void)
45{
46 set_gpio_input();
47 read(gpio_in, &gpio, sizeof(gpio));
48 if (gpio&pin)
49 return OK;
50 else
51 return ERROR;
52}
53#endif
54
55
56int Phoenix_Init (struct s_reader * reader)
57{
58 call (IO_Serial_InitPnP (reader));
59 IO_Serial_Flush(reader);
60
61#ifdef USE_GPIO //felix: define gpio number used for card detect and reset. ref to globals.h
62 if (reader->detect>4)
63 {
64 gpio_detect=reader->detect-4;
65 pin = 1<<gpio_detect;
66 gpio_outen=open("/dev/gpio/outen",O_RDWR);
67 gpio_out=open("/dev/gpio/out",O_RDWR);
68 gpio_in=open("/dev/gpio/in",O_RDWR);
69 set_gpio_input();
70 }
71#endif
72
73 cs_debug_mask (D_IFD, "IFD: Initializing reader %s type=%d\n", reader->label, reader->typ);
74
75 /* Default serial port settings */
76 if (reader->atr[0] == 0) {
77 call (IO_Serial_SetParams (reader, DEFAULT_BAUDRATE, 8, PARITY_EVEN, 2, IO_SERIAL_HIGH, IO_SERIAL_LOW));
78 IO_Serial_Flush(reader);
79 }
80 return OK;
81}
82
83int Phoenix_GetStatus (struct s_reader * reader, int * status)
84{
85#ifdef USE_GPIO //felix: detect card via defined gpio
86 if (gpio_detect)
87 *status=!get_gpio();
88 else
89#endif
90 {
91 unsigned int modembits=0;
92 if (ioctl(reader->handle, TIOCMGET, &modembits) < 0) {
93 cs_log("ERROR Phoenix_GetStatus: ioctl error in card detection for %s", reader->label);
94 return ERROR;
95 }
96 switch(reader->detect&0x7f)
97 {
98 case 0: *status=(modembits & TIOCM_CAR); break;
99 case 1: *status=(modembits & TIOCM_DSR); break;
100 case 2: *status=(modembits & TIOCM_CTS); break;
101 case 3: *status=(modembits & TIOCM_RNG); break;
102 default: *status=0; // dummy
103 }
104 if (!(reader->detect&0x80))
105 *status=!*status;
106 }
107 return OK;
108}
109
110int Phoenix_Reset (struct s_reader * reader, ATR * atr)
111{
112 cs_debug_mask (D_IFD, "IFD: Resetting card:\n");
113 int ret;
114 int i;
115 unsigned char buf[ATR_MAX_SIZE];
116 int parity[3] = {PARITY_EVEN, PARITY_ODD, PARITY_NONE};
117 call (Phoenix_SetBaudrate (reader, DEFAULT_BAUDRATE));
118 for(i=0; i<3; i++) {
119#ifndef OS_CYGWIN32
120 /*
121 * Pause for 200ms as this might help with the PL2303.
122 * Some users reporting that this breaks cygwin, so we exclude this.
123 */
124 cs_sleepms(200);
125#endif
126 IO_Serial_Flush(reader);
127 call (IO_Serial_SetParity (reader, parity[i]));
128
129 ret = ERROR;
130 cs_sleepms(500); //smartreader in mouse mode needs this
131 IO_Serial_Ioctl_Lock(reader, 1);
132#ifdef USE_GPIO
133 if (gpio_detect)
134 set_gpio(0);
135 else
136#endif
137 IO_Serial_RTS_Set(reader);
138#ifdef OS_CYGWIN32
139 /*
140 * Pause for 200ms as this might help with the PL2303.
141 * Some users reporting that this breaks cygwin, so we went back to 50ms.
142 */
143 cs_sleepms(50);
144#else
145 cs_sleepms(200);
146#endif
147
148#ifdef USE_GPIO //felix: set card reset hi (inactive)
149 if (gpio_detect) {
150 set_gpio_input();
151 }
152 else
153#endif
154 IO_Serial_RTS_Clr(reader);
155
156 cs_sleepms(50);
157 IO_Serial_Ioctl_Lock(reader, 0);
158
159 int n=0;
160 while(n<ATR_MAX_SIZE && !IO_Serial_Read(reader, ATR_TIMEOUT, 1, buf+n))
161 n++;
162 if(n==0)
163 continue;
164 if (ATR_InitFromArray (atr, buf, n) == ATR_OK)
165 ret = OK;
166 // Succesfully retrieve ATR
167 if (ret == OK)
168 break;
169 }
170 IO_Serial_Flush(reader);
171
172/*
173 //PLAYGROUND faking ATR for test purposes only
174 //
175 // sky 919 unsigned char atr_test[] = { 0x3F, 0xFF, 0x13, 0x25, 0x03, 0x10, 0x80, 0x33, 0xB0, 0x0E, 0x69, 0xFF, 0x4A, 0x50, 0x70, 0x00, 0x00, 0x49, 0x54, 0x02, 0x00, 0x00 };
176 // HD+ unsigned char atr_test[] = { 0x3F, 0xFF, 0x95, 0x00, 0xFF, 0x91, 0x81, 0x71, 0xFE, 0x47, 0x00, 0x44, 0x4E, 0x41, 0x53, 0x50, 0x31, 0x34, 0x32, 0x20, 0x52, 0x65, 0x76, 0x47, 0x43, 0x34, 0x63 };
177 // S02 = irdeto unsigned char atr_test[] = { 0x3B, 0x9F, 0x21, 0x0E, 0x49, 0x52, 0x44, 0x45, 0x54, 0x4F, 0x20, 0x41, 0x43, 0x53, 0x03};
178 // conax unsigned char atr_test[] = { 0x3B, 0x24, 0x00, 0x30, 0x42, 0x30, 0x30 };
179 //cryptoworks unsigned char atr_test[] = { 0x3B, 0x78, 0x12, 0x00, 0x00, 0x65, 0xC4, 0x05, 0xFF, 0x8F, 0xF1, 0x90, 0x00 };
180 ATR_InitFromArray (atr, atr_test, sizeof(atr_test));
181 //END OF PLAYGROUND
182*/
183
184 return ret;
185}
186
187int Phoenix_Transmit (struct s_reader * reader, BYTE * buffer, unsigned size, unsigned int block_delay, unsigned int char_delay)
188{
189 unsigned sent=0, to_send = 0;
190
191 for (sent = 0; sent < size; sent = sent + to_send)
192 {
193 /* Calculate number of bytes to send */
194 to_send = MIN(size, MAX_TRANSMIT);
195
196 /* Send data */
197 if ((sent == 0) && (block_delay != char_delay))
198 {
199 call (IO_Serial_Write (reader, block_delay, 1, buffer));
200 call (IO_Serial_Write (reader, char_delay, to_send-1, buffer+1));
201 }
202 else
203 call (IO_Serial_Write (reader, char_delay, to_send, buffer+sent));
204 }
205 return OK;
206}
207
208int Phoenix_Receive (struct s_reader * reader, BYTE * buffer, unsigned size, unsigned int timeout)
209{
210#define IFD_TOWITOKO_TIMEOUT 1000
211
212 /* Read all data bytes with the same timeout */
213 call (IO_Serial_Read (reader, timeout + IFD_TOWITOKO_TIMEOUT, size, buffer));
214 return OK;
215}
216
217int Phoenix_SetBaudrate (struct s_reader * reader, unsigned long baudrate)
218{
219 cs_debug_mask (D_IFD, "IFD: Phoenix Setting baudrate to %lu\n", baudrate);
220
221 /* Get current settings */
222 struct termios tio;
223 call (tcgetattr (reader->handle, &tio) != 0);
224 call (IO_Serial_SetBitrate (reader, baudrate, &tio));
225#ifndef OS_CYGWIN32
226 /*
227 * Pause for 200ms as this might help with the PL2303.
228 * Some users reporting that this breaks cygwin, so we exclude this.
229 */
230 cs_sleepms(200);
231#endif
232 call (IO_Serial_SetProperties(reader, tio));
233#ifndef OS_CYGWIN32
234 /*
235 * Pause for 200ms as this might help with the PL2303.
236 * Some users reporting that this breaks cygwin, so we exclude this.
237 */
238 cs_sleepms(200);
239#endif
240 reader->current_baudrate = baudrate; //so if update fails, reader->current_baudrate is not changed either
241 return OK;
242}
243
244int Phoenix_Close (struct s_reader * reader)
245{
246#ifdef USE_GPIO //felix: close dev if card detected
247 if(gpio_detect)
248 {
249 close(gpio_outen);
250 close(gpio_out);
251 close(gpio_in);
252 }
253#endif
254 IO_Serial_Close(reader);
255 cs_debug_mask (D_IFD, "IFD: Closing phoenix device %s", reader->device);
256 return OK;
257}
258
259
260int Phoenix_FastReset (struct s_reader * reader, int delay)
261{
262 IO_Serial_Ioctl_Lock(reader, 1);
263#ifdef USE_GPIO
264 if (gpio_detect)
265 set_gpio(0);
266 else
267#endif
268 IO_Serial_RTS_Set(reader);
269
270 cs_sleepms(delay);
271
272#ifdef USE_GPIO //felix: set card reset hi (inactive)
273 if (gpio_detect) {
274 set_gpio_input();
275 }
276 else
277#endif
278 IO_Serial_RTS_Clr(reader);
279
280 IO_Serial_Ioctl_Lock(reader, 0);
281
282 cs_sleepms(50);
283
284 IO_Serial_Flush(reader);
285 return 0;
286
287}
Note: See TracBrowser for help on using the repository browser.