source: trunk/csctapi/ifd_phoenix.c@ 2854

Last change on this file since 2854 was 2854, checked in by lattjo, 10 years ago

Added support for AD-Teknik multiprogrammer 3.5 and 3.6.
No need to set it into phoenix mode anymore and also support for clocking cards to 6MHz through oscam config.

  • Property svn:eol-style set to native
File size: 7.2 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
16int gpio_outen,gpio_out,gpio_in;
17unsigned int pin,gpio;
18int gpio_detect=0;
19
20static void set_gpio(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(void)
35{
36 read(gpio_outen, &gpio, sizeof(gpio));
37 gpio &= ~pin;
38 write(gpio_outen, &gpio, sizeof(gpio));
39}
40
41static int get_gpio(void)
42{
43 set_gpio_input();
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_detect=reader->detect-4;
62 pin = 1<<gpio_detect;
63 gpio_outen=open("/dev/gpio/outen",O_RDWR);
64 gpio_out=open("/dev/gpio/out",O_RDWR);
65 gpio_in=open("/dev/gpio/in",O_RDWR);
66 set_gpio_input();
67 }
68#endif
69
70 cs_debug_mask (D_IFD, "IFD: Initializing reader %s type=%d\n", reader->label, reader->typ);
71
72 /* Default serial port settings */
73 if (reader->atr[0] == 0) {
74 call (IO_Serial_SetParams (reader, DEFAULT_BAUDRATE, 8, PARITY_EVEN, 2, IO_SERIAL_HIGH, IO_SERIAL_LOW));
75 IO_Serial_Flush(reader);
76 }
77 return OK;
78}
79
80int Phoenix_GetStatus (struct s_reader * reader, int * status)
81{
82#ifdef USE_GPIO //felix: detect card via defined gpio
83 if (gpio_detect)
84 *status=!get_gpio();
85 else
86#endif
87 {
88 unsigned int modembits=0;
89 if (ioctl(reader->handle, TIOCMGET, &modembits) < 0) {
90 cs_log("ERROR Phoenix_GetStatus: ioctl error in card detection for %s", reader->label);
91 return ERROR;
92 }
93 switch(reader->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->detect&0x80))
102 *status=!*status;
103 }
104 return OK;
105}
106
107int Phoenix_Reset (struct s_reader * reader, ATR * atr)
108{
109 cs_debug_mask (D_IFD, "IFD: Resetting card:\n");
110 int ret;
111 int i;
112 unsigned char buf[ATR_MAX_SIZE];
113 int parity[3] = {PARITY_EVEN, PARITY_ODD, PARITY_NONE};
114 call (Phoenix_SetBaudrate (reader, DEFAULT_BAUDRATE));
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 (gpio_detect)
131 set_gpio(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 (gpio_detect) {
147 set_gpio_input();
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(gpio_detect)
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 (gpio_detect)
262 set_gpio(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 (gpio_detect) {
271 set_gpio_input();
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.