source: trunk/csctapi/ifd_phoenix.c@ 1651

Last change on this file since 1651 was 1651, checked in by merek, 11 years ago

Exclude ump changeset 1736 from OS_CYGWIN - this causes some card detection issues under Cygwin

  • Property svn:eol-style set to native
File size: 6.4 KB
Line 
1/*
2 ifd_phoenix.c
3 This module provides IFD handling functions for Smartmouse/Phoenix reader.
4*/
5
6#include <stdio.h>
7//#include <time.h>
8//#include <string.h>
9//#include "ioctls.h"
10#include "../globals.h"
11#include "atr.h"
12#include <termios.h>
13#include "ifd_phoenix.h"
14#include "icc_async.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 ()
57{
58 call (IO_Serial_InitPnP ());
59 IO_Serial_Flush();
60
61#ifdef USE_GPIO //felix: define gpio number used for card detect and reset. ref to globals.h
62 if (reader[ridx].detect>4)
63 {
64 gpio_detect=reader[ridx].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[ridx].label, reader[ridx].typ);
74
75 /* Default serial port settings */
76 call (IO_Serial_SetParams (DEFAULT_BAUDRATE, 8, PARITY_EVEN, 2, IO_SERIAL_HIGH, IO_SERIAL_LOW));
77 call (Phoenix_SetBaudrate (DEFAULT_BAUDRATE));
78 call (IO_Serial_SetParity (PARITY_EVEN));
79 IO_Serial_Flush();
80 return OK;
81}
82
83int Phoenix_GetStatus (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 call (ioctl(reader[ridx].handle, TIOCMGET,&modembits)<0);
93 switch(reader[ridx].detect&0x7f)
94 {
95 case 0: *status=(modembits & TIOCM_CAR); break;
96 case 1: *status=(modembits & TIOCM_DSR); break;
97 case 2: *status=(modembits & TIOCM_CTS); break;
98 case 3: *status=(modembits & TIOCM_RNG); break;
99 default: *status=0; // dummy
100 }
101 if (!(reader[ridx].detect&0x80))
102 *status=!*status;
103 }
104 return OK;
105}
106
107int Phoenix_Reset (ATR * atr)
108{
109 cs_debug_mask (D_IFD, "IFD: Resetting card:\n");
110 int ret;
111 int i;
112 int parity[3] = {PARITY_EVEN, PARITY_ODD, PARITY_NONE};
113 call (Phoenix_SetBaudrate (DEFAULT_BAUDRATE));
114 for(i=0; i<3; i++) {
115#ifndef OS_CYGWIN
116 /*
117 * Pause for 200ms as this might help with the PL2303.
118 * Some users reporting that this breaks cygwin, so we exclude this.
119 */
120 cs_sleepms(200);
121#endif
122 IO_Serial_Flush();
123 call (IO_Serial_SetParity (parity[i]));
124
125 ret = ERROR;
126 cs_sleepms(500); //smartreader in mouse mode needs this
127 IO_Serial_Ioctl_Lock(1);
128#ifdef USE_GPIO
129 if (gpio_detect)
130 set_gpio(0);
131 else
132#endif
133 IO_Serial_RTS_Set();
134#ifdef OS_CYGWIN
135 /*
136 * Pause for 200ms as this might help with the PL2303.
137 * Some users reporting that this breaks cygwin, so we went back to 50ms.
138 */
139 cs_sleepms(50);
140#else
141 cs_sleepms(200);
142#endif
143
144#ifdef USE_GPIO //felix: set card reset hi (inactive)
145 if (gpio_detect) {
146 set_gpio_input();
147 }
148 else
149#endif
150 IO_Serial_RTS_Clr();
151#ifndef OS_CYGWIN
152 /*
153 * Pause for 200ms as this might help with the PL2303.
154 * Some users reporting that this breaks cygwin, so we exclude this.
155 */
156 cs_sleepms(200);
157#endif
158 IO_Serial_Ioctl_Lock(0);
159 if(ATR_InitFromStream (atr, ATR_TIMEOUT) == ATR_OK)
160 ret = OK;
161 // Succesfully retrieve ATR
162 if (ret == OK)
163 break;
164 }
165 IO_Serial_Flush();
166
167/*
168 //PLAYGROUND faking ATR for test purposes only
169 //
170 // 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 };
171 // 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 };
172 // S02 = irdeto unsigned char atr_test[] = { 0x3B, 0x9F, 0x21, 0x0E, 0x49, 0x52, 0x44, 0x45, 0x54, 0x4F, 0x20, 0x41, 0x43, 0x53, 0x03};
173 // conax unsigned char atr_test[] = { 0x3B, 0x24, 0x00, 0x30, 0x42, 0x30, 0x30 };
174 //cryptoworks unsigned char atr_test[] = { 0x3B, 0x78, 0x12, 0x00, 0x00, 0x65, 0xC4, 0x05, 0xFF, 0x8F, 0xF1, 0x90, 0x00 };
175 ATR_InitFromArray (atr, atr_test, sizeof(atr_test));
176 //END OF PLAYGROUND
177*/
178
179 return ret;
180}
181
182int Phoenix_Transmit (BYTE * buffer, unsigned size, unsigned int block_delay, unsigned int char_delay)
183{
184 unsigned sent=0, to_send = 0;
185
186 for (sent = 0; sent < size; sent = sent + to_send)
187 {
188 /* Calculate number of bytes to send */
189 to_send = MIN(size, MAX_TRANSMIT);
190
191 /* Send data */
192 if ((sent == 0) && (block_delay != char_delay))
193 {
194 call (IO_Serial_Write (block_delay, 1, buffer));
195 call (IO_Serial_Write (char_delay, to_send-1, buffer+1));
196 }
197 else
198 call (IO_Serial_Write (char_delay, to_send, buffer+sent));
199 }
200 return OK;
201}
202
203int Phoenix_Receive (BYTE * buffer, unsigned size, unsigned int timeout)
204{
205#define IFD_TOWITOKO_TIMEOUT 1000
206
207 /* Read all data bytes with the same timeout */
208 call (IO_Serial_Read (timeout + IFD_TOWITOKO_TIMEOUT, size, buffer));
209 return OK;
210}
211
212int Phoenix_SetBaudrate (unsigned long baudrate)
213{
214 cs_debug_mask (D_IFD, "IFD: Phoenix Setting baudrate to %lu\n", baudrate);
215 if (current_baudrate != baudrate)
216 {
217 /* Get current settings */
218 struct termios tio;
219 call (tcgetattr (reader[ridx].handle, &tio) != 0);
220 call (IO_Serial_SetBitrate (baudrate, &tio));
221#ifndef OS_CYGWIN
222 /*
223 * Pause for 200ms as this might help with the PL2303.
224 * Some users reporting that this breaks cygwin, so we exclude this.
225 */
226 cs_sleepms(200);
227#endif
228 call (IO_Serial_SetProperties(tio));
229#ifndef OS_CYGWIN
230 /*
231 * Pause for 200ms as this might help with the PL2303.
232 * Some users reporting that this breaks cygwin, so we exclude this.
233 */
234 cs_sleepms(200);
235#endif
236 }
237 current_baudrate = baudrate; //so if update fails, current_baudrate is not changed either
238 return OK;
239}
240
241int Phoenix_Close ()
242{
243#ifdef USE_GPIO //felix: close dev if card detected
244 if(gpio_detect)
245 {
246 close(gpio_outen);
247 close(gpio_out);
248 close(gpio_in);
249 }
250#endif
251 IO_Serial_Close();
252 cs_debug_mask (D_IFD, "IFD: Closing phoenix device %s", reader[ridx].device);
253 return OK;
254}
Note: See TracBrowser for help on using the repository browser.