source: trunk/csctapi/ifd_phoenix.c@ 3428

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

reverting changes from rev 3420, will work with original reporter of ticket 994

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