1 | /*
|
---|
2 | ifd_sci.c
|
---|
3 | This module provides IFD handling functions for SCI internal reader.
|
---|
4 | */
|
---|
5 |
|
---|
6 | #include "../globals.h"
|
---|
7 |
|
---|
8 | #ifdef CARDREADER_INTERNAL_SCI
|
---|
9 |
|
---|
10 | #include "../oscam-time.h"
|
---|
11 |
|
---|
12 | #include "atr.h"
|
---|
13 | #include "ifd_sci_global.h"
|
---|
14 | #include "ifd_sci_ioctl.h"
|
---|
15 | #include "io_serial.h"
|
---|
16 | #include "../oscam-string.h"
|
---|
17 |
|
---|
18 | #define OK 0
|
---|
19 | #define ERROR 1
|
---|
20 |
|
---|
21 | struct sr_data
|
---|
22 | {
|
---|
23 | uint8_t old_reset;
|
---|
24 | unsigned char T;
|
---|
25 | uint32_t fs;
|
---|
26 | uint32_t ETU;
|
---|
27 | uint32_t WWT;
|
---|
28 | uint32_t CWT;
|
---|
29 | uint32_t BWT;
|
---|
30 | uint32_t EGT;
|
---|
31 | unsigned char P;
|
---|
32 | unsigned char I;
|
---|
33 | };
|
---|
34 |
|
---|
35 | static int32_t Sci_GetStatus(struct s_reader *reader, int32_t *status)
|
---|
36 | {
|
---|
37 | call (ioctl(reader->handle, IOCTL_GET_IS_CARD_PRESENT, status)<0);
|
---|
38 | return OK;
|
---|
39 | }
|
---|
40 |
|
---|
41 | static int32_t Sci_Deactivate(struct s_reader *reader)
|
---|
42 | {
|
---|
43 | int32_t in = 0 ;
|
---|
44 | rdr_log(reader, "Deactivating card");
|
---|
45 | if (ioctl(reader->handle, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
|
---|
46 | {
|
---|
47 | rdr_log(reader, "Error:%s ioctl(IOCTL_GET_IS_CARD_PRESENT) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
|
---|
48 | return ERROR;
|
---|
49 | }
|
---|
50 | if (in != 1) {ioctl(reader->handle, IOCTL_GET_IS_CARD_ACTIVATED, &in);}
|
---|
51 |
|
---|
52 | if(in && boxtype_is("dm8000"))
|
---|
53 | {
|
---|
54 | if((ioctl(reader->handle, IOCTL_SET_DEACTIVATE)<0))
|
---|
55 | {
|
---|
56 | rdr_log(reader,"ioctl(IOCTL_SET_DEACTIVATE) not supported on %s", boxtype_get());
|
---|
57 | return ERROR;
|
---|
58 | }
|
---|
59 | }
|
---|
60 | else {return ERROR;}
|
---|
61 |
|
---|
62 | return OK;
|
---|
63 |
|
---|
64 | }
|
---|
65 |
|
---|
66 | static int32_t Sci_Activate(struct s_reader *reader)
|
---|
67 | {
|
---|
68 | rdr_log_dbg(reader, D_IFD, "Is card present?");
|
---|
69 | int32_t in = 0;
|
---|
70 | if (ioctl(reader->handle, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
|
---|
71 | {
|
---|
72 | rdr_log(reader, "Error:%s ioctl(IOCTL_GET_IS_CARD_PRESENT) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
|
---|
73 | Sci_Deactivate(reader);
|
---|
74 | return ERROR;
|
---|
75 | }
|
---|
76 | if (in != 1) {ioctl(reader->handle, IOCTL_GET_IS_CARD_ACTIVATED, &in);}
|
---|
77 |
|
---|
78 | if (in)
|
---|
79 | {
|
---|
80 | cs_sleepms(50);
|
---|
81 | return OK;
|
---|
82 | }
|
---|
83 | else
|
---|
84 | {
|
---|
85 | rdr_log(reader, "Error: no card is present in readerslot!");
|
---|
86 | Sci_Deactivate(reader);
|
---|
87 | return ERROR;
|
---|
88 | }
|
---|
89 | }
|
---|
90 |
|
---|
91 | static int32_t Sci_Read_ATR(struct s_reader *reader, ATR *atr) // reads ATR on the fly: reading and some low levelchecking at the same time
|
---|
92 | {
|
---|
93 | uint32_t timeout = ATR_TIMEOUT;
|
---|
94 | unsigned char buf[SCI_MAX_ATR_SIZE];
|
---|
95 | int32_t n = 0, statusreturn = 0;
|
---|
96 |
|
---|
97 | if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) //read first char of atr
|
---|
98 | {
|
---|
99 | rdr_log(reader, "ERROR: no characters found in ATR!");
|
---|
100 | return ERROR;
|
---|
101 | }
|
---|
102 | if(buf[0] == 0x3F) // 3F: card is using inverse convention, 3B = card is using direct convention
|
---|
103 | {
|
---|
104 | rdr_log_dbg(reader, D_IFD, "This card uses inverse convention");
|
---|
105 | }
|
---|
106 | else { rdr_log_dbg(reader, D_IFD, "This card uses direct convention"); }
|
---|
107 | n++;
|
---|
108 | if(IO_Serial_Read(reader, 0, timeout, 1, buf + n))
|
---|
109 | {
|
---|
110 | rdr_log_dbg(reader, D_IFD, "ERROR: only 1 character found in ATR");
|
---|
111 | return ERROR;
|
---|
112 | }
|
---|
113 | int32_t T0 = buf[n];
|
---|
114 | int32_t historicalbytes = T0 & 0x0F; // num of historical bytes in lower nibble of T0 byte
|
---|
115 | rdr_log_dbg(reader, D_ATR, "ATR historicalbytes should be: %d", historicalbytes);
|
---|
116 | rdr_log_dbg(reader, D_ATR, "Fetching global interface characters for protocol T0"); // protocol T0 always aboard!
|
---|
117 | n++;
|
---|
118 |
|
---|
119 | int32_t protocols = 1, tck = 0, protocol, protocolnumber; // protocols = total protocols on card, tck = checksum byte present, protocol = mandatory protocol
|
---|
120 | int32_t D = 0; // protocolnumber = TDi uses protocolnumber
|
---|
121 | int32_t TDi = T0; // place T0 char into TDi for looped parsing.
|
---|
122 | while(n < SCI_MAX_ATR_SIZE)
|
---|
123 | {
|
---|
124 | if(TDi & 0x10) //TA Present: //The value of TA(i) is always interpreted as XI || UI if i > 2 and T = 15 ='F'in TD(i�1)
|
---|
125 | {
|
---|
126 | if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; } //In this case, TA(i) contains the clock stop indicator XI, which indicates the logical
|
---|
127 | //state the clockline must assume when the clock is stopped, and the class indicator UI,
|
---|
128 | rdr_log_dbg(reader, D_ATR, "TA%d: %02X", protocols, buf[n]); //which specifies the supply voltage class.
|
---|
129 | if((protocols > 2) && ((TDi & 0x0F) == 0x0F)) // Protocol T15 does not exists, it means mandatory on all ATRs
|
---|
130 | {
|
---|
131 | if((buf[n] & 0xC0) == 0xC0) { rdr_log_dbg(reader, D_ATR, "Clockline low or high on clockstop"); }
|
---|
132 | if((buf[n] & 0xC0) == 0x00) { rdr_log_dbg(reader, D_ATR, "Clockline not supported on clockstop"); }
|
---|
133 | if((buf[n] & 0xC0) == 0x40) { rdr_log_dbg(reader, D_ATR, "Clockline should be low on clockstop"); }
|
---|
134 | if((buf[n] & 0xC0) == 0x80) { rdr_log_dbg(reader, D_ATR, "Clockline should be high on clockstop"); }
|
---|
135 | if((buf[n] & 0x3F) == 0x01) { rdr_log_dbg(reader, D_ATR, "Voltage class A 4.5~5.5V"); }
|
---|
136 | if((buf[n] & 0x3F) == 0x02) { rdr_log_dbg(reader, D_ATR, "Voltage class B 2.7~3.3V"); }
|
---|
137 | if((buf[n] & 0x3F) == 0x03) { rdr_log_dbg(reader, D_ATR, "Voltage class A 4.5~5.5V and class B 2.7~3.3V"); }
|
---|
138 | if((buf[n] & 0x3F) == 0x04) { rdr_log_dbg(reader, D_ATR, "Voltage RFU"); }
|
---|
139 | }
|
---|
140 | if((protocols > 2) && ((TDi & 0x0F) == 0x01)) // Protocol T1 specfic (There is always an obsolete T0 protocol!)
|
---|
141 | {
|
---|
142 | int32_t ifsc = buf[n];
|
---|
143 | if(ifsc == 0x00) { ifsc = 32; } //default is 32
|
---|
144 | rdr_log_dbg(reader, D_ATR, "Maximum information field length this card can receive is %d bytes (IFSC)", ifsc);
|
---|
145 | }
|
---|
146 |
|
---|
147 | if(protocols < 2)
|
---|
148 | {
|
---|
149 | int32_t FI = (buf[n] >> 4); // FI is high nibble ***** work ETU = (1/D)*(Frequencydivider/cardfrequency) (in seconds!)
|
---|
150 | int32_t Fi = atr_f_table[FI]; // lookup the frequency divider
|
---|
151 | float fmax = atr_fs_table[FI]; // lookup the max frequency ***** initial ETU = 372 / initial frequency during atr (in seconds!)
|
---|
152 |
|
---|
153 | int32_t DI = (buf[n] & 0x0F); // DI is low nibble
|
---|
154 | D = atr_d_table[DI]; // lookup the bitrate adjustment (yeah there are floats in it, but in iso only integers!?)
|
---|
155 | rdr_log_dbg(reader, D_ATR, "Advertised max cardfrequency is %.2f (Fmax), frequency divider is %d (Fi)", fmax / 1000000L, Fi); // High nibble TA1 contains cardspeed
|
---|
156 | rdr_log_dbg(reader, D_ATR, "Bitrate adjustment is %d (D)", D); // Low nibble TA1 contains Bitrateadjustment
|
---|
157 | rdr_log_dbg(reader, D_ATR, "Work ETU = %.2f us assuming card runs at %.2f Mhz",
|
---|
158 | (double)((1 / (double)D) * ((double)Fi / (double)fmax) * 1000000), fmax / 1000000L); // And display it...
|
---|
159 | rdr_log_dbg(reader, D_ATR, "Initial ETU = %.2f us", (double)372 / (double)fmax * 1000000); // And display it... since D=1 and frequency during ATR fetch might be different!
|
---|
160 | }
|
---|
161 | if(protocols > 1 && protocols < 3)
|
---|
162 | {
|
---|
163 | if((buf[n] & 0x80) == 0x80) { rdr_log_dbg(reader, D_ATR, "Switching between negotiable mode and specific mode is not possible"); }
|
---|
164 | else
|
---|
165 | {
|
---|
166 | rdr_log_dbg(reader, D_ATR, "Switching between negotiable mode and specific mode is possible");
|
---|
167 | // int32_t PPS = 1; Stupid compiler, will need it later on eventually
|
---|
168 | }
|
---|
169 | if((buf[n] & 0x01) == 0x01) { rdr_log_dbg(reader, D_ATR, "Transmission parameters implicitly defined in the interface characters."); }
|
---|
170 | else { rdr_log_dbg(reader, D_ATR, "Transmission parameters explicitly defined in the interface characters."); }
|
---|
171 |
|
---|
172 | protocol = buf[n] & 0x0F;
|
---|
173 | if(protocol) { rdr_log_dbg(reader, D_ATR, "Protocol T = %d is to be used!", protocol); }
|
---|
174 | }
|
---|
175 | n++; // next interface character
|
---|
176 | }
|
---|
177 | if(TDi & 0x20) //TB Present
|
---|
178 | {
|
---|
179 | if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; }
|
---|
180 | rdr_log_dbg(reader, D_ATR, "TB%d: %02X", protocols, buf[n]);
|
---|
181 | if((protocols > 2) && ((TDi & 0x0F) == 0x01)) // Protocol T1 specfic (There is always an obsolete T0 protocol!)
|
---|
182 | {
|
---|
183 | int32_t CWI = (buf[n] & 0x0F); // low nibble contains CWI code for the character waiting time CWT
|
---|
184 | int32_t BWI = (buf[n] >> 4); // high nibble contains BWI code for the block waiting time BWT
|
---|
185 | rdr_log_dbg(reader, D_ATR, "Protocol T1: Character waiting time is %d(CWI)", CWI);
|
---|
186 | rdr_log_dbg(reader, D_ATR, "Protocol T1: Block waiting time is %d (BWI)", BWI);
|
---|
187 | }
|
---|
188 |
|
---|
189 | n++; // next interface character
|
---|
190 | }
|
---|
191 | if(TDi & 0x40) //TC Present
|
---|
192 | {
|
---|
193 | if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; }
|
---|
194 | rdr_log_dbg(reader, D_ATR, "TC%d: %02X", protocols, buf[n]);
|
---|
195 | if((protocols > 1) && ((TDi & 0x0F) == 0x00))
|
---|
196 | {
|
---|
197 | int32_t WI = buf[n];
|
---|
198 | rdr_log_dbg(reader, D_ATR, "Protocol T0: work wait time is %d work etu (WWT)", (int)(960 * D * WI));
|
---|
199 | }
|
---|
200 | if((protocols > 1) && ((TDi & 0x0F) == 0x01))
|
---|
201 | {
|
---|
202 | if(buf[n] & 0x01) { rdr_log_dbg(reader, D_ATR, "Protocol T1: CRC is used to compute the error detection code"); }
|
---|
203 | else { rdr_log_dbg(reader, D_ATR, "Protocol T1: LRC is used to compute the error detection code"); }
|
---|
204 | }
|
---|
205 | if((protocols < 2) && (buf[n] < 0xFF)) { rdr_log_dbg(reader, D_ATR, "Extra guardtime of %d ETU (N)", (int) buf[n]); }
|
---|
206 | if((protocols < 2) && (buf[n] == 0xFF)) { rdr_log_dbg(reader, D_ATR, "Protocol T1: Standard 2 ETU guardtime is lowered to 1 ETU"); }
|
---|
207 |
|
---|
208 | n++; // next interface character
|
---|
209 | }
|
---|
210 | if(TDi & 0x80) //TD Present? Get next TDi there will be a next protocol
|
---|
211 | {
|
---|
212 | if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; }
|
---|
213 | rdr_log_dbg(reader, D_ATR, "TD%d %02X", protocols, buf[n]);
|
---|
214 | TDi = buf[n];
|
---|
215 | protocolnumber = TDi & 0x0F;
|
---|
216 | if(protocolnumber == 0x00) { tck = 0; } // T0 protocol do not use tck byte (TCK = checksum byte!)
|
---|
217 | if(protocolnumber == 0x0E) { tck = 1; } // T14 protocol tck byte should be present
|
---|
218 | if(protocolnumber == 0x01) { tck = 1; } // T1 protocol tck byte is mandatory, BTW: this code doesnt calculate if the TCK is valid jet...
|
---|
219 | rdr_log_dbg(reader, D_ATR, "Fetching global interface characters for protocol T%d:", (TDi & 0x0F)); // lower nibble contains protocol number
|
---|
220 | protocols++; // there is always 1 protocol T0 in every ATR as per iso defined, max is 16 (numbered 0..15)
|
---|
221 |
|
---|
222 | n++; // next interface character
|
---|
223 | }
|
---|
224 | else { break; }
|
---|
225 | }
|
---|
226 | int32_t atrlength = 0;
|
---|
227 | atrlength += n;
|
---|
228 | atrlength += historicalbytes;
|
---|
229 | rdr_log_dbg(reader, D_ATR, "Total ATR Length including %d historical bytes should be %d", historicalbytes, atrlength);
|
---|
230 | if(T0 & 0x80) { protocols--; } // if bit 8 set there was a TD1 and also more protocols, otherwise this is a T0 card: substract 1 from total protocols
|
---|
231 | rdr_log_dbg(reader, D_ATR, "Total protocols in this ATR is %d", protocols);
|
---|
232 |
|
---|
233 | while(n < atrlength + tck) // read all the rest and mandatory tck byte if other protocol than T0 is used.
|
---|
234 | {
|
---|
235 | if(IO_Serial_Read(reader, 0, timeout, 1, buf + n)) { break; }
|
---|
236 | n++;
|
---|
237 | }
|
---|
238 |
|
---|
239 | if(n != atrlength + tck) { rdr_log(reader, "WARNING: Total ATR characters received is: %d instead of expected %d", n, atrlength + tck); }
|
---|
240 |
|
---|
241 | if((buf[0] != 0x3B) && (buf[0] != 0x3F) && (n > 9 && !memcmp(buf + 4, "IRDETO", 6))) // irdeto S02 reports FD as first byte on dreambox SCI, not sure about SH4 or phoenix
|
---|
242 | { buf[0] = 0x3B; }
|
---|
243 |
|
---|
244 | statusreturn = ATR_InitFromArray(atr, buf, n); // n should be same as atr length but in case of atr read error it's less, so do not use atr length here!
|
---|
245 |
|
---|
246 | if(buf[7] == 0x70 && buf[8] == 0x70 && (buf[9]&0x0F) >= 10)
|
---|
247 | {
|
---|
248 | const struct s_cardreader *crdr_ops = reader->crdr;
|
---|
249 | if (!crdr_ops) return ERROR;
|
---|
250 | int8_t nxtr = 0;
|
---|
251 | reader->crdr_flush = 0;
|
---|
252 | while(nxtr < 2)
|
---|
253 | {
|
---|
254 | if(IO_Serial_Read(reader, 0, 75000, 1, buf + n + nxtr)) { break; }
|
---|
255 | nxtr++;
|
---|
256 | }
|
---|
257 | }
|
---|
258 |
|
---|
259 | if(statusreturn == ATR_MALFORMED) { rdr_log(reader, "WARNING: ATR is malformed, you better inspect it with a -d2 log!"); }
|
---|
260 |
|
---|
261 | if(statusreturn == ERROR)
|
---|
262 | {
|
---|
263 | rdr_log(reader, "WARNING: ATR is invalid!");
|
---|
264 | return ERROR;
|
---|
265 | }
|
---|
266 |
|
---|
267 | return OK; // return OK but atr might be softfailing!
|
---|
268 | }
|
---|
269 |
|
---|
270 | static int32_t Sci_Reset(struct s_reader *reader, ATR *atr)
|
---|
271 | {
|
---|
272 | int32_t ret = ERROR;
|
---|
273 |
|
---|
274 | SCI_PARAMETERS params;
|
---|
275 |
|
---|
276 | memset(¶ms, 0, sizeof(SCI_PARAMETERS));
|
---|
277 |
|
---|
278 | params.ETU = 372; //initial ETU (in iso this parameter F)
|
---|
279 | params.EGT = 0; //initial guardtime should be 0 (in iso this is parameter N)
|
---|
280 | params.fs = 3; //initial cardmhz 3 Mhz for non pll readers (in iso this is parameter D)
|
---|
281 | params.T = 0;
|
---|
282 | if(reader->cardmhz > 2000) // PLL based reader
|
---|
283 | {
|
---|
284 | params.ETU = 372;
|
---|
285 | params.EGT = 0;
|
---|
286 | params.fs = (int32_t)(reader->cardmhz / 100.0 + 0.5); /* calculate divider for 1 MHz */
|
---|
287 | params.T = 0;
|
---|
288 | }
|
---|
289 | if(reader->cardmhz == 8300) /* PLL based reader DM7025 */
|
---|
290 | {
|
---|
291 | params.ETU = 372;
|
---|
292 | params.EGT = 0;
|
---|
293 | params.fs = 16; /* read from table setting for 1 MHz:
|
---|
294 | params.fs = 6 for cardmhz = 5.188 MHz
|
---|
295 | params.fs = 7 for cardmhz = 4.611 MHz
|
---|
296 | params.fs = 8 for cardmhz = 3.953 MHz
|
---|
297 | params.fs = 9 for cardmhz = 3.609 MHz
|
---|
298 | params.fs = 10 for cardmhz = 3.192 MHz
|
---|
299 | params.fs = 11 for cardmhz = 2.965 MHz
|
---|
300 | params.fs = 12 for cardmhz = 2.677 MHz
|
---|
301 | params.fs = 13 for cardmhz = 2.441 MHz
|
---|
302 | params.fs = 14 for cardmhz = 2.306 MHz
|
---|
303 | params.fs = 15 for cardmhz = 2.128 MHz
|
---|
304 | params.fs = 16 for cardmhz = 1.977 MHz */
|
---|
305 | params.T = 0;
|
---|
306 | }
|
---|
307 |
|
---|
308 | int32_t tries = 0;
|
---|
309 | int32_t max_tries = 0;
|
---|
310 | int32_t pll_start_fs = 0;
|
---|
311 | if (reader->cardmhz > 2000 && reader->cardmhz != 8300)
|
---|
312 | {
|
---|
313 | max_tries = (((double)(reader->cardmhz/900)) * 2 ) + 1 ; // the higher the maxpll the higher tries needed, to have 9 Mhz or first avb below.
|
---|
314 | pll_start_fs = ((double)(reader->cardmhz/300)) + 1.5 ; // first avbl reader Mhz equal or above 3.0 Mhz
|
---|
315 | }
|
---|
316 | else
|
---|
317 | {
|
---|
318 | max_tries = 5;
|
---|
319 | }
|
---|
320 | while(ret == ERROR && tries < max_tries)
|
---|
321 | {
|
---|
322 | cs_sleepms(50);
|
---|
323 | // rdr_log(reader, "Set reader parameters!");
|
---|
324 | rdr_log_dbg(reader, D_IFD, "Sent reader setting at cardinit T=%d fs=%d ETU=%d WWT=%d CWT=%d BWT=%d EGT=%d clock=%d check=%d P=%d I=%d U=%d",
|
---|
325 | (int)params.T, params.fs, (int)params.ETU, (int)params.WWT,
|
---|
326 | (int)params.CWT, (int)params.BWT, (int)params.EGT,
|
---|
327 | (int)params.clock_stop_polarity, (int)params.check,
|
---|
328 | (int)params.P, (int)params.I, (int)params.U);
|
---|
329 | ioctl(reader->handle, IOCTL_SET_PARAMETERS, ¶ms);
|
---|
330 | cs_sleepms(150); // give the reader some time to process the params
|
---|
331 |
|
---|
332 | // rdr_log(reader, "Reset internal cardreader!");
|
---|
333 | if(ioctl(reader->handle, IOCTL_SET_RESET, 1) < 0)
|
---|
334 | {
|
---|
335 | ret = ERROR;
|
---|
336 | rdr_log(reader, "Error:%s ioctl(IOCTL_SET_RESET) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
|
---|
337 | Sci_Deactivate(reader);
|
---|
338 | Sci_Activate(reader);
|
---|
339 | cs_sleepms(50);
|
---|
340 | }
|
---|
341 | else
|
---|
342 | {
|
---|
343 | ret = Sci_Read_ATR(reader, atr);
|
---|
344 | if(ret == ERROR)
|
---|
345 | {
|
---|
346 | Sci_Deactivate(reader);
|
---|
347 | Sci_Activate(reader);
|
---|
348 | if (reader->cardmhz > 2000 && reader->cardmhz != 8300)
|
---|
349 | {
|
---|
350 | tries++; // increase fs
|
---|
351 | params.fs = (pll_start_fs - tries); // if 1 Mhz init failed retry with min 300 Mhz up to max 9.0 Mhz
|
---|
352 | rdr_log(reader, "Read ATR fail, attempt %d/%d fs = %d", tries, max_tries, params.fs);
|
---|
353 | }
|
---|
354 | else if (reader->cardmhz > 2000 && reader->cardmhz == 8300)
|
---|
355 | {
|
---|
356 | tries++; // increase fs
|
---|
357 | params.fs = (11 - tries); // if 1 Mhz init failed retry with 3.19 Mhz up to 5.188 Mhz
|
---|
358 | rdr_log(reader, "Read ATR fail, attempt %d/5 fs = %d", tries, params.fs);
|
---|
359 | }
|
---|
360 | else
|
---|
361 | {
|
---|
362 | tries++; // increase fs
|
---|
363 | params.fs = (2 + tries); // if 1 Mhz init failed retry with 3.0 Mhz up to 7.0 Mhz
|
---|
364 | rdr_log(reader, "Read ATR fail, attempt %d/5 fs = %d", tries, params.fs);
|
---|
365 | }
|
---|
366 | }
|
---|
367 | else // ATR fetched successfully!
|
---|
368 | {
|
---|
369 | if(ioctl(reader->handle, IOCTL_SET_ATR_READY, 1) < 0)
|
---|
370 | {
|
---|
371 | ret = ERROR;
|
---|
372 | rdr_log(reader, "Error:%s ioctl(IOCTL_SET_ATR_READY) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
|
---|
373 | }
|
---|
374 | }
|
---|
375 | }
|
---|
376 | }
|
---|
377 | return ret;
|
---|
378 | }
|
---|
379 |
|
---|
380 | static int32_t Sci_WriteSettings(struct s_reader *reader, unsigned char T, uint32_t fs, uint32_t ETU, uint32_t WWT, uint32_t CWT, uint32_t BWT, uint32_t EGT, unsigned char P, unsigned char I)
|
---|
381 | {
|
---|
382 | cs_sleepms(150);
|
---|
383 | struct sr_data *crdr_data = reader->crdr_data;
|
---|
384 | //int32_t n;
|
---|
385 | SCI_PARAMETERS params;
|
---|
386 | //memset(¶ms,0,sizeof(SCI_PARAMETERS));
|
---|
387 | ioctl(reader->handle, IOCTL_GET_PARAMETERS, ¶ms);
|
---|
388 | params.T = T;
|
---|
389 | params.fs = fs;
|
---|
390 |
|
---|
391 | //for Irdeto T14 cards, do not set ETU
|
---|
392 | if(ETU)
|
---|
393 | { params.ETU = ETU; }
|
---|
394 | params.EGT = EGT;
|
---|
395 | params.WWT = WWT;
|
---|
396 | params.BWT = BWT;
|
---|
397 | params.CWT = CWT;
|
---|
398 | if(P)
|
---|
399 | { params.P = P; }
|
---|
400 | if(I)
|
---|
401 | { params.I = I; }
|
---|
402 |
|
---|
403 | crdr_data->T = params.T;
|
---|
404 | crdr_data->fs = params.fs;
|
---|
405 | crdr_data->ETU = params.ETU;
|
---|
406 | crdr_data->WWT = params.WWT;
|
---|
407 | crdr_data->CWT = params.CWT;
|
---|
408 | crdr_data->BWT = params.BWT;
|
---|
409 | crdr_data->EGT = params.EGT;
|
---|
410 | crdr_data->P = params.P;
|
---|
411 | crdr_data->I = params.I;
|
---|
412 |
|
---|
413 | rdr_log_dbg(reader, D_IFD, "Sent reader settings T=%d fs=%d ETU=%d WWT=%d CWT=%d BWT=%d EGT=%d clock=%d check=%d P=%d I=%d U=%d",
|
---|
414 | (int)params.T, params.fs, (int)params.ETU, (int)params.WWT,
|
---|
415 | (int)params.CWT, (int)params.BWT, (int)params.EGT,
|
---|
416 | (int)params.clock_stop_polarity, (int)params.check,
|
---|
417 | (int)params.P, (int)params.I, (int)params.U);
|
---|
418 |
|
---|
419 | ioctl(reader->handle, IOCTL_SET_PARAMETERS, ¶ms);
|
---|
420 | cs_sleepms(150); // give the reader some time to process the params
|
---|
421 | return OK;
|
---|
422 | }
|
---|
423 |
|
---|
424 | static int32_t Sci_FastReset(struct s_reader *reader, ATR *atr)
|
---|
425 | {
|
---|
426 | struct sr_data *crdr_data = reader->crdr_data;
|
---|
427 | int8_t atr_ok = 1; // initiate atr in ERROR
|
---|
428 | uint32_t timeout = ATR_TIMEOUT;
|
---|
429 | unsigned char buf[SCI_MAX_ATR_SIZE];
|
---|
430 | int8_t atr_len = 0;
|
---|
431 |
|
---|
432 | if(reader->seca_nagra_card == 1)
|
---|
433 | {
|
---|
434 | atr_len = reader->card_atr_length; // this is a special case the data buffer has only the atr length.
|
---|
435 | }
|
---|
436 | else
|
---|
437 | {
|
---|
438 | atr_len = reader->card_atr_length + 2; // data buffer has atr length + 2 bytes
|
---|
439 | }
|
---|
440 |
|
---|
441 | Sci_Activate(reader);
|
---|
442 | cs_sleepms(50);
|
---|
443 | if(ioctl(reader->handle, IOCTL_SET_RESET, 1) < 0)
|
---|
444 | {
|
---|
445 | rdr_log(reader, "Error:%s ioctl(IOCTL_SET_RESET) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
|
---|
446 | Sci_Deactivate(reader);
|
---|
447 | atr_ok = ERROR;
|
---|
448 | }
|
---|
449 | else
|
---|
450 | {
|
---|
451 | IO_Serial_Read(reader, 0, timeout*10, atr_len, buf); //read atr: give some extra timeout time since on some platforms all chars are read at once
|
---|
452 | // rdr_log_dump(reader,buf, SCI_MAX_ATR_SIZE * 2, "SCI ATR :"); // just to crosscheck the buffer I left it commented.
|
---|
453 | if(ioctl(reader->handle, IOCTL_SET_ATR_READY, 1) < 0)
|
---|
454 | {
|
---|
455 | rdr_log(reader, "Error:%s ioctl(IOCTL_SET_ATR_READY) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) );
|
---|
456 | Sci_Deactivate(reader);
|
---|
457 | atr_ok = ERROR;
|
---|
458 | }
|
---|
459 | else
|
---|
460 | {
|
---|
461 | if(ATR_InitFromArray(atr, buf, atr_len) != ERROR)
|
---|
462 | {
|
---|
463 | atr_ok = OK;
|
---|
464 | }
|
---|
465 | else
|
---|
466 | {
|
---|
467 | rdr_log(reader,"Error reading ATR");
|
---|
468 | atr_ok= ERROR;
|
---|
469 | }
|
---|
470 |
|
---|
471 | cs_sleepms(150);
|
---|
472 | Sci_WriteSettings(reader, crdr_data->T,crdr_data->fs,crdr_data->ETU, crdr_data->WWT,crdr_data->CWT,crdr_data->BWT,crdr_data->EGT,crdr_data->P,crdr_data->I);
|
---|
473 | cs_sleepms(150);
|
---|
474 | }
|
---|
475 | }
|
---|
476 | return atr_ok;
|
---|
477 | }
|
---|
478 |
|
---|
479 | static int32_t Sci_Init(struct s_reader *reader)
|
---|
480 | {
|
---|
481 | uint8_t i = 0;
|
---|
482 | while(reader->handle_nr > 0 && i < 5)
|
---|
483 | {
|
---|
484 | i++;
|
---|
485 | rdr_log(reader," Wait On closing before restart %u", i);
|
---|
486 | cs_sleepms(1000);
|
---|
487 | }
|
---|
488 |
|
---|
489 | int flags = O_RDWR | O_NOCTTY;
|
---|
490 | #if defined(__SH4__) || defined(STB04SCI)
|
---|
491 | flags |= O_NONBLOCK;
|
---|
492 | reader->sh4_stb = 1;
|
---|
493 | #endif
|
---|
494 | reader->handle = open(reader->device, flags);
|
---|
495 | if(reader->handle < 0)
|
---|
496 | {
|
---|
497 | rdr_log(reader, "ERROR: Opening device %s (errno=%d %s)", reader->device, errno, strerror(errno));
|
---|
498 | return ERROR;
|
---|
499 | }
|
---|
500 |
|
---|
501 | if(!reader->crdr_data && !cs_malloc(&reader->crdr_data, sizeof(struct sr_data)))
|
---|
502 | { return ERROR; }
|
---|
503 | struct sr_data *crdr_data = reader->crdr_data;
|
---|
504 | crdr_data->old_reset = 1;
|
---|
505 | reader->handle_nr = reader->handle + 1;
|
---|
506 | return OK;
|
---|
507 | }
|
---|
508 |
|
---|
509 | static int32_t sci_activate(struct s_reader *reader, ATR *atr)
|
---|
510 | {
|
---|
511 | if(!reader->ins7e11_fast_reset)
|
---|
512 | {
|
---|
513 | call(Sci_Activate(reader));
|
---|
514 | call(Sci_Reset(reader, atr));
|
---|
515 | }
|
---|
516 | else
|
---|
517 | {
|
---|
518 | rdr_log_dbg(reader, D_IFD, "Fast card reset with atr");
|
---|
519 | call(Sci_FastReset(reader, atr));
|
---|
520 | }
|
---|
521 | return OK;
|
---|
522 | }
|
---|
523 |
|
---|
524 | static int32_t Sci_Close(struct s_reader *reader)
|
---|
525 | {
|
---|
526 | Sci_Deactivate(reader);
|
---|
527 | IO_Serial_Close(reader);
|
---|
528 | NULLFREE(reader->crdr_data); //clearing allocated module mem
|
---|
529 | NULLFREE(reader->csystem_data); //clearing allocated card system mem
|
---|
530 | cs_sleepms(150); // some stb's needs small extra time even after close procedure seems to be ok.
|
---|
531 | reader->handle_nr = 0;
|
---|
532 | return OK;
|
---|
533 | }
|
---|
534 |
|
---|
535 | static int32_t sci_write_settings(struct s_reader *reader, struct s_cardreader_settings *s)
|
---|
536 | {
|
---|
537 | if(reader->cardmhz > 2000) // only for dreambox internal pll readers clockspeed can be set precise others like vu ignore it and work always at 4.5 Mhz
|
---|
538 | {
|
---|
539 | // P fixed at 5V since this is default class A card, and TB is deprecated
|
---|
540 | if(reader->protocol_type != ATR_PROTOCOL_TYPE_T14) // fix VU+ internal reader slow responses on T0/T1
|
---|
541 | {
|
---|
542 | cs_sleepms(150);
|
---|
543 | call(Sci_WriteSettings(reader, 0, reader->divider, s->ETU, s->WWT, reader->CWT, reader->BWT, s->EGT, 5, (unsigned char)s->I));
|
---|
544 | cs_sleepms(150);
|
---|
545 | }
|
---|
546 | else // no fixup for T14 protocol otherwise error
|
---|
547 | {
|
---|
548 | cs_sleepms(150);
|
---|
549 | call(Sci_WriteSettings(reader, reader->protocol_type, reader->divider, s->ETU, s->WWT, reader->CWT, reader->BWT, s->EGT, 5, (unsigned char)s->I));
|
---|
550 | cs_sleepms(150);
|
---|
551 | }
|
---|
552 | }
|
---|
553 | else // all other brand boxes than dreamboxes or VU+!
|
---|
554 | {
|
---|
555 | // P fixed at 5V since this is default class A card, and TB is deprecated
|
---|
556 | cs_sleepms(150);
|
---|
557 | // non pll internal reader needs base frequency like 1,2,3,4,5,6 MHz not clock rate conversion factor (Fi)
|
---|
558 | call(Sci_WriteSettings(reader, reader->protocol_type, s->F/100, s->ETU, s->WWT, reader->CWT, reader->BWT, s->EGT, 5, (unsigned char)s->I));
|
---|
559 | cs_sleepms(150);
|
---|
560 | }
|
---|
561 | return OK;
|
---|
562 | }
|
---|
563 |
|
---|
564 | const struct s_cardreader cardreader_internal_sci =
|
---|
565 | {
|
---|
566 | .desc = "internal",
|
---|
567 | .typ = R_INTERNAL,
|
---|
568 | .flush = 1,
|
---|
569 | .max_clock_speed = 1,
|
---|
570 | .reader_init = Sci_Init,
|
---|
571 | .get_status = Sci_GetStatus,
|
---|
572 | .activate = sci_activate,
|
---|
573 | .transmit = IO_Serial_Transmit,
|
---|
574 | .receive = IO_Serial_Receive,
|
---|
575 | .close = Sci_Close,
|
---|
576 | .write_settings = sci_write_settings,
|
---|
577 | };
|
---|
578 |
|
---|
579 | #endif
|
---|