source: trunk/csctapi/ifd_phoenix.c@ 4149

Last change on this file since 4149 was 4149, checked in by dingo35, 12 years ago

checked some routines on threadsafety

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