source: branches/smartreader/csctapi/ifd_phoenix.c@ 1271

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

resync with trunk

File size: 7.2 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.h" //FIXME kill this after IFD timings
14
15#define OK 1
16#define ERROR 0
17
18#define IFD_TOWITOKO_MAX_TRANSMIT 255
19#define IFD_TOWITOKO_ATR_TIMEOUT 800
20#define IFD_TOWITOKO_BAUDRATE 9600
21
22#ifdef USE_GPIO //felix: definition of gpio functions
23int gpio_outen,gpio_out,gpio_in;
24unsigned int pin,gpio;
25int gpio_detect=0;
26
27static void set_gpio(int level)
28{
29 read(gpio_outen, &gpio, sizeof(gpio));
30 gpio |= pin;
31 write(gpio_outen, &gpio, sizeof(gpio));
32
33 read(gpio_out, &gpio, sizeof(gpio));
34 if (level>0)
35 gpio|=pin;
36 else
37 gpio&=~pin;
38 write(gpio_out, &gpio, sizeof(gpio));
39}
40
41static void set_gpio_input(void)
42{
43 read(gpio_outen, &gpio, sizeof(gpio));
44 gpio &= ~pin;
45 write(gpio_outen, &gpio, sizeof(gpio));
46}
47
48static int get_gpio(void)
49{
50 set_gpio_input();
51 read(gpio_in, &gpio, sizeof(gpio));
52 return ((int)((gpio&pin)?1:0));
53}
54#endif
55
56
57int Phoenix_Init ()
58{
59#ifdef USE_GPIO //felix: define gpio number used for card detect and reset. ref to globals.h
60 extern int oscam_card_detect;
61 if (oscam_card_detect>4)
62 {
63 gpio_detect=oscam_card_detect-4;
64 pin = 1<<gpio_detect;
65 gpio_outen=open("/dev/gpio/outen",O_RDWR);
66 gpio_out=open("/dev/gpio/out",O_RDWR);
67 gpio_in=open("/dev/gpio/in",O_RDWR);
68 set_gpio_input();
69 }
70#endif
71
72#ifdef DEBUG_IFD
73 printf ("IFD: Initializing slot number %d, com=%d\n", slot, reader[ridx].typ);
74#endif
75
76 if(reader[ridx].typ == R_INTERNAL) //not sure whether this should be moved in front of GPIO part
77 return OK;
78
79 /* Default serial port settings */
80 if (!IO_Serial_SetParams (IFD_TOWITOKO_BAUDRATE, 8, PARITY_EVEN, 2, IO_SERIAL_HIGH, IO_SERIAL_LOW))
81 {
82 reader[ridx].status = 0;//added this one because it seemed logical
83 return ERROR;
84 }
85
86 if (!Phoenix_SetBaudrate(IFD_TOWITOKO_BAUDRATE))
87 {
88 reader[ridx].status = 0;
89 return ERROR;
90 }
91
92 if (!IO_Serial_SetParity (PARITY_EVEN))
93 {
94 reader[ridx].status = 0;
95 return ERROR;
96 }
97
98 IO_Serial_Flush();
99 return OK;
100}
101
102int Phoenix_GetStatus (int * status)
103{
104#ifdef USE_GPIO //felix: detect card via defined gpio
105 if (gpio_detect)
106 *status=get_gpio();
107 else
108#endif
109 {
110 unsigned int modembits=0;
111 extern int oscam_card_detect; //FIXME kill global variable
112 if (ioctl(reader[ridx].handle, TIOCMGET,&modembits)<0)
113 return ERROR;
114 switch(oscam_card_detect&0x7f)
115 {
116 case 0: *status=(modembits & TIOCM_CAR); break;
117 case 1: *status=(modembits & TIOCM_DSR); break;
118 case 2: *status=(modembits & TIOCM_CTS); break;
119 case 3: *status=(modembits & TIOCM_RNG); break;
120 default: *status=0; // dummy
121 }
122 if (!(oscam_card_detect&0x80))
123 *status=!*status;
124 }
125 return OK;
126}
127
128int Phoenix_Reset (ATR ** atr)
129{
130
131#ifdef DEBUG_IFD
132 printf ("IFD: Resetting card:\n");
133#endif
134
135 int ret;
136 int i;
137 int parity[3] = {PARITY_EVEN, PARITY_ODD, PARITY_NONE};
138#ifdef HAVE_NANOSLEEP
139 struct timespec req_ts;
140 req_ts.tv_sec = 0;
141 req_ts.tv_nsec = 50000000;
142#endif
143
144 (*atr) = NULL;
145 for(i=0; i<3; i++) {
146 IO_Serial_Flush();
147 if (!IO_Serial_SetParity (parity[i]))
148 return ERROR;
149
150 ret = ERROR;
151 IO_Serial_Ioctl_Lock(1);
152#ifdef USE_GPIO
153 if (gpio_detect)
154 set_gpio(0);
155 else
156#endif
157 IO_Serial_RTS_Set();
158#ifdef HAVE_NANOSLEEP
159 nanosleep (&req_ts, NULL);
160#else
161 usleep (50000L);
162#endif
163#ifdef USE_GPIO //felix: set card reset hi (inactive)
164 if (gpio_detect) {
165 set_gpio_input();
166 }
167 else
168#endif
169 IO_Serial_RTS_Clr();
170 IO_Serial_Ioctl_Lock(0);
171 (*atr) = ATR_New ();
172 if(ATR_InitFromStream ((*atr), IFD_TOWITOKO_ATR_TIMEOUT) == ATR_OK)
173 ret = OK;
174 // Succesfully retrieve ATR
175 if (ret == OK)
176 break;
177 else
178 {
179 ATR_Delete (*atr);
180 (*atr) = NULL;
181 }
182 }
183 IO_Serial_Flush();
184
185/*
186 //PLAYGROUND faking ATR for test purposes only
187 //
188 // 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 };
189 // 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 };
190 // S02 = irdeto unsigned char atr_test[] = { 0x3B, 0x9F, 0x21, 0x0E, 0x49, 0x52, 0x44, 0x45, 0x54, 0x4F, 0x20, 0x41, 0x43, 0x53, 0x03};
191 //cryptoworks unsigned char atr_test[] = { 0x3B, 0x78, 0x12, 0x00, 0x00, 0x65, 0xC4, 0x05, 0xFF, 0x8F, 0xF1, 0x90, 0x00 };
192 ATR_Delete(*atr); //throw away actual ATR
193 (*atr) = ATR_New ();
194 ATR_InitFromArray ((*atr), atr_test, sizeof(atr_test));
195 //END OF PLAYGROUND
196*/
197
198 return ret;
199}
200
201int Phoenix_Transmit (BYTE * buffer, unsigned size, IFD_Timings * timings)
202{
203 unsigned block_delay, char_delay, sent=0, to_send = 0;
204
205#ifdef DEBUG_IFD
206 printf ("IFD: Transmit: ");
207 for (sent = 0; sent < size; sent++)
208 printf ("%X ", buffer[sent]);
209 printf ("\n");
210#endif
211
212#define IFD_TOWITOKO_DELAY 0
213
214 /* Calculate delays */
215 char_delay = IFD_TOWITOKO_DELAY + timings->char_delay;
216 block_delay = IFD_TOWITOKO_DELAY + timings->block_delay;
217
218 for (sent = 0; sent < size; sent = sent + to_send)
219 {
220 /* Calculate number of bytes to send */
221 to_send = MIN(size, IFD_TOWITOKO_MAX_TRANSMIT);
222
223 /* Send data */
224 if ((sent == 0) && (block_delay != char_delay))
225 {
226 if (!IO_Serial_Write (block_delay, 1, buffer))
227 return ERROR;
228
229 if (!IO_Serial_Write (char_delay, to_send-1, buffer+1))
230 return ERROR;
231 }
232 else
233 {
234 if (!IO_Serial_Write (char_delay, to_send, buffer+sent))
235 return ERROR;
236 }
237 }
238 return OK;
239}
240
241int Phoenix_Receive (BYTE * buffer, unsigned size, IFD_Timings * timings)
242{
243 unsigned char_timeout, block_timeout;
244#ifdef DEBUG_IFD
245 int i;
246#endif
247
248#define IFD_TOWITOKO_TIMEOUT 1000
249
250 /* Calculate timeouts */
251 char_timeout = IFD_TOWITOKO_TIMEOUT + timings->char_timeout;
252 block_timeout = IFD_TOWITOKO_TIMEOUT + timings->block_timeout;
253 if (block_timeout != char_timeout)
254 {
255 /* Read first byte using block timeout */
256 if (!IO_Serial_Read (block_timeout, 1, buffer))
257 return ERROR;
258
259 if (size > 1)
260 {
261 /* Read remaining data bytes using char timeout */
262 if (!IO_Serial_Read (char_timeout, size - 1, buffer + 1))
263 return ERROR;
264 }
265 }
266 else
267 {
268 /* Read all data bytes with the same timeout */
269 if (!IO_Serial_Read (char_timeout, size, buffer))
270 return ERROR;
271 }
272
273#ifdef DEBUG_IFD
274 printf ("IFD: Receive: ");
275 for (i = 0; i < size; i++)
276 printf ("%X ", buffer[i]);
277 printf ("\n");
278#endif
279
280 return OK;
281}
282
283int Phoenix_SetBaudrate (unsigned long baudrate)
284{
285 if(reader[ridx].typ == R_INTERNAL)
286 return OK;
287
288#ifdef DEBUG_IFD
289 printf ("IFD: Setting baudrate to %lu\n", baudrate);
290#endif
291 if (reader[ridx].baudrate == baudrate)
292 return OK;
293
294 /* Get current settings */
295 struct termios tio;
296 if (tcgetattr (reader[ridx].handle, &tio) != 0)
297 return ERROR;
298
299 //write baudrate here!
300 if (!IO_Serial_SetBitrate (baudrate, &tio))
301 return ERROR;
302
303 if (!IO_Serial_SetProperties(tio))
304 return ERROR;
305
306 reader[ridx].baudrate = baudrate;
307
308 return OK;
309}
310
311int Phoenix_Close ()
312{
313#ifdef USE_GPIO //felix: close dev if card detected
314 if(gpio_detect)
315 {
316 close(gpio_outen);
317 close(gpio_out);
318 close(gpio_in);
319 }
320#endif
321
322#ifdef DEBUG_IFD
323 printf ("IFD: Closing slot\n");
324#endif
325
326 reader[ridx].status = 0;
327 return OK;
328}
Note: See TracBrowser for help on using the repository browser.