source: trunk/csctapi/ifd_phoenix.c@ 3181

Last change on this file since 3181 was 3181, checked in by dingo35, 10 years ago

Adding threadsafety FIXMEs, feel free to join checking..

  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1//FIXME Not checked on threadsafety yet; after checking please remove this line
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
17int gpio_outen,gpio_out,gpio_in;
18unsigned int pin,gpio;
19int gpio_detect=0;
20
21static void set_gpio(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(void)
36{
37 read(gpio_outen, &gpio, sizeof(gpio));
38 gpio &= ~pin;
39 write(gpio_outen, &gpio, sizeof(gpio));
40}
41
42static int get_gpio(void)
43{
44 set_gpio_input();
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_detect=reader->detect-4;
63 pin = 1<<gpio_detect;
64 gpio_outen=open("/dev/gpio/outen",O_RDWR);
65 gpio_out=open("/dev/gpio/out",O_RDWR);
66 gpio_in=open("/dev/gpio/in",O_RDWR);
67 set_gpio_input();
68 }
69#endif
70
71 cs_debug_mask (D_IFD, "IFD: Initializing reader %s type=%d\n", reader->label, reader->typ);
72
73 /* Default serial port settings */
74 if (reader->atr[0] == 0) {
75 call (IO_Serial_SetParams (reader, DEFAULT_BAUDRATE, 8, PARITY_EVEN, 2, IO_SERIAL_HIGH, IO_SERIAL_LOW));
76 IO_Serial_Flush(reader);
77 }
78 return OK;
79}
80
81int Phoenix_GetStatus (struct s_reader * reader, int * status)
82{
83#ifdef USE_GPIO //felix: detect card via defined gpio
84 if (gpio_detect)
85 *status=!get_gpio();
86 else
87#endif
88 {
89 unsigned int modembits=0;
90 if (ioctl(reader->handle, TIOCMGET, &modembits) < 0) {
91 cs_log("ERROR Phoenix_GetStatus: ioctl error in card detection for %s", reader->label);
92 return ERROR;
93 }
94 switch(reader->detect&0x7f)
95 {
96 case 0: *status=(modembits & TIOCM_CAR); break;
97 case 1: *status=(modembits & TIOCM_DSR); break;
98 case 2: *status=(modembits & TIOCM_CTS); break;
99 case 3: *status=(modembits & TIOCM_RNG); break;
100 default: *status=0; // dummy
101 }
102 if (!(reader->detect&0x80))
103 *status=!*status;
104 }
105 return OK;
106}
107
108int Phoenix_Reset (struct s_reader * reader, ATR * atr)
109{
110 cs_debug_mask (D_IFD, "IFD: Resetting card:\n");
111 int ret;
112 int i;
113 unsigned char buf[ATR_MAX_SIZE];
114 int parity[3] = {PARITY_EVEN, PARITY_ODD, PARITY_NONE};
115 call (Phoenix_SetBaudrate (reader, DEFAULT_BAUDRATE));
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 (gpio_detect)
132 set_gpio(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 (gpio_detect) {
148 set_gpio_input();
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(gpio_detect)
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 (gpio_detect)
263 set_gpio(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 (gpio_detect) {
272 set_gpio_input();
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.