source: trunk/reader-irdeto.c@ 4149

Last change on this file since 4149 was 4141, checked in by dingo35, 13 years ago

all: simplify debug system, add D_DVBAPI = -d128, eliminate cs_ptyp which complicates stuff unnecc

File size: 18.4 KB
Line 
1#include "globals.h"
2#include "reader-common.h"
3
4static const uchar CryptTable[256] =
5{
6 0xDA, 0x26, 0xE8, 0x72, 0x11, 0x52, 0x3E, 0x46,
7 0x32, 0xFF, 0x8C, 0x1E, 0xA7, 0xBE, 0x2C, 0x29,
8 0x5F, 0x86, 0x7E, 0x75, 0x0A, 0x08, 0xA5, 0x21,
9 0x61, 0xFB, 0x7A, 0x58, 0x60, 0xF7, 0x81, 0x4F,
10 0xE4, 0xFC, 0xDF, 0xB1, 0xBB, 0x6A, 0x02, 0xB3,
11 0x0B, 0x6E, 0x5D, 0x5C, 0xD5, 0xCF, 0xCA, 0x2A,
12 0x14, 0xB7, 0x90, 0xF3, 0xD9, 0x37, 0x3A, 0x59,
13 0x44, 0x69, 0xC9, 0x78, 0x30, 0x16, 0x39, 0x9A,
14 0x0D, 0x05, 0x1F, 0x8B, 0x5E, 0xEE, 0x1B, 0xC4,
15 0x76, 0x43, 0xBD, 0xEB, 0x42, 0xEF, 0xF9, 0xD0,
16 0x4D, 0xE3, 0xF4, 0x57, 0x56, 0xA3, 0x0F, 0xA6,
17 0x50, 0xFD, 0xDE, 0xD2, 0x80, 0x4C, 0xD3, 0xCB,
18 0xF8, 0x49, 0x8F, 0x22, 0x71, 0x84, 0x33, 0xE0,
19 0x47, 0xC2, 0x93, 0xBC, 0x7C, 0x3B, 0x9C, 0x7D,
20 0xEC, 0xC3, 0xF1, 0x89, 0xCE, 0x98, 0xA2, 0xE1,
21 0xC1, 0xF2, 0x27, 0x12, 0x01, 0xEA, 0xE5, 0x9B,
22 0x25, 0x87, 0x96, 0x7B, 0x34, 0x45, 0xAD, 0xD1,
23 0xB5, 0xDB, 0x83, 0x55, 0xB0, 0x9E, 0x19, 0xD7,
24 0x17, 0xC6, 0x35, 0xD8, 0xF0, 0xAE, 0xD4, 0x2B,
25 0x1D, 0xA0, 0x99, 0x8A, 0x15, 0x00, 0xAF, 0x2D,
26 0x09, 0xA8, 0xF5, 0x6C, 0xA1, 0x63, 0x67, 0x51,
27 0x3C, 0xB2, 0xC0, 0xED, 0x94, 0x03, 0x6F, 0xBA,
28 0x3F, 0x4E, 0x62, 0x92, 0x85, 0xDD, 0xAB, 0xFE,
29 0x10, 0x2E, 0x68, 0x65, 0xE7, 0x04, 0xF6, 0x0C,
30 0x20, 0x1C, 0xA9, 0x53, 0x40, 0x77, 0x2F, 0xA4,
31 0xFA, 0x6D, 0x73, 0x28, 0xE2, 0xCD, 0x79, 0xC8,
32 0x97, 0x66, 0x8E, 0x82, 0x74, 0x06, 0xC7, 0x88,
33 0x1A, 0x4A, 0x6B, 0xCC, 0x41, 0xE9, 0x9D, 0xB8,
34 0x23, 0x9F, 0x3D, 0xBF, 0x8D, 0x95, 0xC5, 0x13,
35 0xB9, 0x24, 0x5A, 0xDC, 0x64, 0x18, 0x38, 0x91,
36 0x7F, 0x5B, 0x70, 0x54, 0x07, 0xB6, 0x4B, 0x0E,
37 0x36, 0xAC, 0x31, 0xE6, 0xD6, 0x48, 0xAA, 0xB4
38};
39
40static const uchar
41 sc_GetCountryCode[] = { 0x02, 0x02, 0x03, 0x00, 0x00 };
42
43static const uchar
44 sc_GetCountryCode2[]= { 0x02, 0x0B, 0x00, 0x00, 0x00 },
45 sc_GetCamKey384CZ[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
46 0x18, 0xD7, 0x55, 0x14, 0xC0, 0x83, 0xF1, 0x38,
47 0x39, 0x6F, 0xF2, 0xEC, 0x4F, 0xE3, 0xF1, 0x85,
48 0x01, 0x46, 0x06, 0xCE, 0x7D, 0x08, 0x2C, 0x74,
49 0x46, 0x8F, 0x72, 0xC4, 0xEA, 0xD7, 0x9C, 0xE0,
50 0xE1, 0xFF, 0x58, 0xE7, 0x70, 0x0C, 0x92, 0x45,
51 0x26, 0x18, 0x4F, 0xA0, 0xE2, 0xF5, 0x9E, 0x46,
52 0x6F, 0xAE, 0x95, 0x35, 0xB0, 0x49, 0xB2, 0x0E,
53 0xA4, 0x1F, 0x8E, 0x47, 0xD0, 0x24, 0x11, 0xD0 },
54 sc_GetCamKey384DZ[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
55 0x27, 0xF2, 0xD6, 0xCD, 0xE6, 0x88, 0x62, 0x46,
56 0x81, 0xB0, 0xF5, 0x3E, 0x6F, 0x13, 0x4D, 0xCC,
57 0xFE, 0xD0, 0x67, 0xB1, 0x93, 0xDD, 0xF4, 0xDE,
58 0xEF, 0xF5, 0x3B, 0x04, 0x1D, 0xE5, 0xC3, 0xB2,
59 0x54, 0x38, 0x57, 0x7E, 0xC8, 0x39, 0x07, 0x2E,
60 0xD2, 0xF4, 0x05, 0xAA, 0x15, 0xB5, 0x55, 0x24,
61 0x90, 0xBB, 0x9B, 0x00, 0x96, 0xF0, 0xCB, 0xF1,
62 0x8A, 0x08, 0x7F, 0x0B, 0xB8, 0x79, 0xC3, 0x5D },
63 sc_GetCamKey384FZ[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
64 0x62, 0xFE, 0xD8, 0x4F, 0x44, 0x86, 0x2C, 0x21,
65 0x50, 0x9A, 0xBE, 0x27, 0x15, 0x9E, 0xC4, 0x48,
66 0xF3, 0x73, 0x5C, 0xBD, 0x08, 0x64, 0x6D, 0x13,
67 0x64, 0x90, 0x14, 0xDB, 0xFF, 0xC3, 0xFE, 0x03,
68 0x97, 0xFA, 0x75, 0x08, 0x12, 0xF9, 0x8F, 0x84,
69 0x83, 0x17, 0xAA, 0x6F, 0xEF, 0x2C, 0x10, 0x1B,
70 0xBF, 0x31, 0x41, 0xC3, 0x54, 0x2F, 0x65, 0x50,
71 0x95, 0xA9, 0x64, 0x22, 0x5E, 0xA4, 0xAF, 0xA9 };
72
73typedef struct chid_base_date {
74 ushort caid;
75 ushort acs;
76 char c_code[4];
77 long base;
78} CHID_BASE_DATE;
79
80static void XRotateLeft8Byte(uchar *buf)
81{
82 int k;
83 uchar t1=buf[7];
84 uchar t2=0;
85 for(k=0; k<=7; k++)
86 {
87 t2=t1;
88 t1=buf[k];
89 buf[k]=(buf[k]<<1)|(t2>>7);
90 }
91}
92
93static void ReverseSessionKeyCrypt(const uchar *camkey, uchar *key)
94{
95 uchar localkey[8], tmp1, tmp2;
96 int idx1,idx2;
97
98 memcpy(localkey, camkey, 8) ;
99 for(idx1=0; idx1<8; idx1++)
100 {
101 for(idx2=0; idx2<8; idx2++)
102 {
103 tmp1 = CryptTable[key[7] ^ localkey[idx2] ^ idx1] ;
104 tmp2 = key[0] ;
105 key[0] = key[1] ;
106 key[1] = key[2] ;
107 key[2] = key[3] ;
108 key[3] = key[4] ;
109 key[4] = key[5] ;
110 key[5] = key[6] ^ tmp1 ;
111 key[6] = key[7] ;
112 key[7] = tmp1 ^ tmp2 ;
113 }
114 XRotateLeft8Byte(localkey);
115 }
116}
117
118static time_t chid_date(struct s_reader * reader, ulong date, char *buf, int l)
119{
120
121 // Irdeto date starts 01.08.1997 which is
122 // 870393600 seconds in unix calendar time
123 //
124 // The above might not be true for all Irdeto card
125 // we need to find a way to identify cards to set the base date
126 // like we did for NDS
127 //
128 // this is the known default value.
129 long date_base=870393600L; // this is actually 31.07.1997, 17:00
130 // CAID, ACS, Country, base date D . M. Y, h : m
131 CHID_BASE_DATE table[] = { {0x0604, 0x1541, "GRC", 977817600L}, // 26.12.2000, 00:00
132 {0x0604, 0x1542, "GRC", 977817600L}, // 26.12.2000, 00:00
133 {0x0604, 0x1543, "GRC", 977817600L}, // 26.12.2000, 00:00
134 {0x0604, 0x1544, "GRC", 977817600L}, // 26.12.2000, 17:00
135 {0x0628, 0x0606, "MCR", 1159574400L}, // 29.09.2006, 00:00
136 {0x0604, 0x0608, "EGY", 999993600L}, // 08.09.2001, 17:00
137 {0x0604, 0x0606, "EGY", 1003276800L}, // 16.10.2001, 17:00
138 {0x0627, 0x0608, "EGY", 946598400L}, // 30.12.1999, 16:00
139 {0x0664, 0x0608, "TUR", 946598400L}, // 31.12.1999, 00:00
140 // {0x1702, 0x0384, "AUT", XXXXXXXXXL}, // -> we need the base date for this
141 // {0x1702, 0x0384, "GER", 888883200L}, // 02.03.1998, 16:00 -> this fixes some card but break others (S02).
142 {0x0, 0x0, "", 0L}
143 };
144
145 // now check for specific providers base date
146 int i=0;
147 while(table[i].caid) {
148 if(reader->caid[0]==table[i].caid && reader->acs==table[i].acs && !memcmp(reader->country_code,table[i].c_code,3) ) {
149 date_base = table[i].base;
150 break;
151 }
152 i++;
153 }
154
155 time_t ut=date_base+date*(24*3600);
156 if (buf) {
157 struct tm *t;
158 t=gmtime(&ut);
159 snprintf(buf, l, "%04d/%02d/%02d", t->tm_year+1900, t->tm_mon+1, t->tm_mday);
160 }
161 return(ut);
162}
163
164static int irdeto_do_cmd(struct s_reader * reader, uchar *buf, ushort good, uchar * cta_res, ushort * p_cta_lr)
165{
166 int rc;
167 if( (rc = reader_cmd2icc(reader, buf, buf[4] + 5, cta_res, p_cta_lr)) )
168 return(rc); // result may be 0 (success) or negative
169 if (*p_cta_lr < 2)
170 return(0x7F7F); // this should never happen
171 return(good != b2i(2, cta_res+*p_cta_lr-2));
172}
173
174#define reader_chk_cmd(cmd, l) \
175{ \
176 if (reader_cmd2icc(reader, cmd, sizeof(cmd), cta_res, &cta_lr)) return ERROR; \
177 if (l && (cta_lr!=l)) return ERROR; }
178
179static int irdeto_card_init_provider(struct s_reader * reader)
180{
181 def_resp;
182 int i, p;
183 uchar buf[256] = {0};
184
185 uchar sc_GetProvider[] = { 0x02, 0x03, 0x03, 0x00, 0x00 };
186
187 /*
188 * Provider
189 */
190 memset(reader->prid, 0xff, sizeof(reader->prid));
191 for (buf[0] = i = p = 0; i<reader->nprov; i++)
192 {
193 sc_GetProvider[3] = i;
194 reader_chk_cmd(sc_GetProvider, 0);
195 //if ((cta_lr==26) && (cta_res[0]!=0xf))
196 if ((cta_lr == 26) && ((!(i&1)) || (cta_res[0] != 0xf)))
197 {
198 reader->prid[i][4] = p++;
199
200 // maps the provider id for Betacrypt from FFFFFF to 000000,
201 // fixes problems with cascading CCcam and OSCam
202 if ((reader->caid[0] >= 0x1700) && (reader->caid[0] <= 0x1799))
203 memset(&reader->prid[i][0], 0, 4);
204 else
205 memcpy(&reader->prid[i][0], cta_res, 4);
206
207 sprintf((char *) buf+strlen((char *)buf), ",%06lx", b2i(3, &reader->prid[i][1]));
208 }
209 else
210 reader->prid[i][0] = 0xf;
211 }
212 if (p)
213 cs_ri_log(reader, "active providers: %d (%s)", p, buf + 1);
214
215 return OK;
216}
217
218
219
220static int irdeto_card_init(struct s_reader * reader, ATR newatr)
221{
222 def_resp;
223 get_atr;
224 int camkey = 0;
225 uchar buf[256] = {0};
226 uchar sc_GetCamKey383C[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
227 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
228 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
229 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
230 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
231 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
232 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
233 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
234 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
235
236 uchar sc_GetASCIISerial[] = { 0x02, 0x00, 0x03, 0x00, 0x00 },
237 sc_GetHEXSerial[] = { 0x02, 0x01, 0x00, 0x00, 0x00 },
238 sc_GetCardFile[] = { 0x02, 0x0E, 0x02, 0x00, 0x00 };
239
240 if (memcmp(atr+4, "IRDETO", 6))
241 return ERROR;
242 cs_ri_log(reader, "detect irdeto card");
243
244 if(reader->has_rsa && !reader->force_irdeto) // we use rsa from config as camkey
245 {
246 cs_debug_mask(D_READER, "[irdeto-reader] using camkey data from config");
247 memcpy(&sc_GetCamKey383C[5], reader->rsa_mod, 0x40);
248 cs_debug_mask(D_READER, "[irdeto-reader] camkey: %s", cs_hexdump (0, reader->nagra_boxkey, 8));
249 cs_debug_mask(D_READER, "[irdeto-reader] camkey-data: %s", cs_hexdump (0, &sc_GetCamKey383C[5], 32));
250 cs_debug_mask(D_READER, "[irdeto-reader] camkey-data: %s", cs_hexdump (0, &sc_GetCamKey383C[37], 32));
251 } else {
252 memcpy(reader->nagra_boxkey, "\x11\x22\x33\x44\x55\x66\x77\x88", 8);
253 }
254
255 /*
256 * ContryCode
257 */
258 reader_chk_cmd(sc_GetCountryCode, 18);
259 reader->acs = (cta_res[0] << 8) | cta_res[1];
260 reader->caid[0] = (cta_res[5] << 8) | cta_res[6];
261 memcpy(reader->country_code,cta_res + 13, 3);
262 cs_ri_log(reader, "caid: %04X, acs: %x.%02x, country code: %c%c%c",
263 reader->caid[0], cta_res[0], cta_res[1], cta_res[13], cta_res[14], cta_res[15]);
264
265 /*
266 * Ascii/Hex-Serial
267 */
268 reader_chk_cmd(sc_GetASCIISerial, 22);
269 memcpy(buf, cta_res, 10);
270 buf[10] = 0;
271 reader_chk_cmd(sc_GetHEXSerial, 18);
272 memcpy(reader->hexserial, cta_res+12, 8);
273 reader->nprov = cta_res[10];
274 cs_ri_log(reader, "providers: %d, ascii serial: %s, hex serial: %02X%02X%02X, hex base: %02X",
275 reader->nprov, buf, cta_res[12], cta_res[13], cta_res[14], cta_res[15]);
276
277 /*
278 * CardFile
279 */
280 for (sc_GetCardFile[2] = 2; sc_GetCardFile[2] < 4; sc_GetCardFile[2]++)
281 reader_chk_cmd(sc_GetCardFile, 0);
282
283 /*
284 * CamKey
285 */
286 if ((atr[14] == 0x03) && (atr[15] == 0x84) && (atr[16] == 0x55))
287 {
288 switch (reader->caid[0])
289 {
290 case 0x1702: camkey = 1; break;
291 case 0x1722: camkey = 2; break;
292 case 0x1762: camkey = 3; break;
293 default : camkey = 4; break;
294 }
295 }
296
297 cs_debug_mask(D_READER, "[irdeto-reader] set camkey for type=%d", camkey);
298
299 switch (camkey)
300 {
301 case 1:
302 reader_chk_cmd(sc_GetCamKey384CZ, 10);
303 break;
304 case 2:
305 reader_chk_cmd(sc_GetCamKey384DZ, 10);
306 break;
307 case 3:
308 reader_chk_cmd(sc_GetCamKey384FZ, 10);
309 break;
310 default:
311 reader_chk_cmd(sc_GetCamKey383C, 0);
312 break;
313 }
314 if (reader->cardmhz != 600)
315 cs_log("WARNING: For Irdeto cards you will have to set 'cardmhz = 600' in oscam.server");
316
317 return irdeto_card_init_provider(reader);
318}
319
320int irdeto_do_ecm(struct s_reader * reader, ECM_REQUEST *er)
321{
322 def_resp; cta_lr = 0; //suppress compiler error
323 static const uchar sc_EcmCmd[] = { 0x05, 0x00, 0x00, 0x02, 0x00 };
324 uchar cta_cmd[272];
325
326 memcpy(cta_cmd, sc_EcmCmd, sizeof(sc_EcmCmd));
327 cta_cmd[4] = (er->ecm[2]) - 3;
328 memcpy(cta_cmd + sizeof(sc_EcmCmd), &er->ecm[6], cta_cmd[4]);
329
330 if (irdeto_do_cmd(reader, cta_cmd, 0x9D00, cta_res, &cta_lr)) {
331 if(cta_lr >= 2)
332 snprintf( er->msglog, MSGLOGSIZE, "irdeto_do_cmd [%d] %02x %02x", cta_lr, cta_res[cta_lr - 2], cta_res[cta_lr - 1] );
333 else
334 snprintf( er->msglog, MSGLOGSIZE, "irdeto_do_cmd [%d]<2", cta_lr);
335
336 return ERROR;
337 }
338
339 if (cta_lr < 24) {
340 snprintf( er->msglog, MSGLOGSIZE, "cta_lr (%d) < 24",cta_lr );
341 return ERROR;
342 }
343
344 ReverseSessionKeyCrypt(reader->nagra_boxkey, cta_res+6);
345 ReverseSessionKeyCrypt(reader->nagra_boxkey, cta_res+14);
346 memcpy(er->cw, cta_res + 6, 16);
347 return OK;
348}
349
350static int irdeto_get_emm_type(EMM_PACKET *ep, struct s_reader * rdr) {
351
352 int i, l = (ep->emm[3]&0x07);
353 int base = (ep->emm[3]>>3);
354 char dumprdrserial[l*3];
355
356 cs_debug_mask(D_EMM, "Entered irdeto_get_emm_type ep->emm[3]=%02x",ep->emm[3]);
357
358 switch (l) {
359
360 case 0:
361 // global emm, 0 bytes addressed
362 ep->type = GLOBAL;
363 cs_debug_mask(D_EMM, "IRDETO EMM: GLOBAL");
364 return TRUE;
365
366 case 2:
367 // shared emm, 2 bytes addressed
368 ep->type = SHARED;
369 memset(ep->hexserial, 0, 8);
370 memcpy(ep->hexserial, ep->emm + 4, l);
371 strcpy(dumprdrserial, cs_hexdump(1, rdr->hexserial, l));
372 cs_debug_mask(D_EMM, "IRDETO EMM: SHARED l = %d ep = %s rdr = %s base = %02x", l,
373 cs_hexdump(1, ep->hexserial, l), dumprdrserial, base);
374
375 if (base & 0x10) {
376 // hex addressed
377 return (base == rdr->hexserial[3] && !memcmp(ep->emm + 4, rdr->hexserial, l));
378 }
379 else {
380 // not hex addressed and emm mode zero
381 if (base == 0)
382 return TRUE;
383
384 // provider addressed
385 for(i = 0; i < rdr->nprov; i++)
386 if (base == rdr->prid[i][0] && !memcmp(ep->emm + 4, &rdr->prid[i][1], l))
387 return TRUE;
388 }
389 cs_debug_mask(D_EMM, "IRDETO EMM: neither hex nor provider addressed or unknown provider id");
390 return FALSE;
391
392 case 3:
393 // unique emm, 3 bytes addressed
394 ep->type = UNIQUE;
395 memset(ep->hexserial, 0, 8);
396 memcpy(ep->hexserial, ep->emm + 4, l);
397 strcpy(dumprdrserial, cs_hexdump(1, rdr->hexserial, l));
398 cs_debug_mask(D_EMM, "IRDETO EMM: UNIQUE l = %d ep = %s rdr = %s", l,
399 cs_hexdump(1, ep->hexserial, l), dumprdrserial);
400
401 return (base == rdr->hexserial[3] && !memcmp(ep->emm + 4, rdr->hexserial, l));
402
403 default:
404 ep->type = UNKNOWN;
405 cs_debug_mask(D_EMM, "IRDETO EMM: UNKNOWN");
406 return TRUE;
407 }
408
409}
410
411static void irdeto_get_emm_filter(struct s_reader * rdr, uchar *filter)
412{
413 filter[0]=0xFF;
414 filter[1]=3;
415
416 int base = rdr->hexserial[3];
417 int emm_g = base * 8;
418 int emm_s = emm_g + 2;
419 int emm_u = emm_g + 3;
420
421 filter[2]=GLOBAL;
422 filter[3]=0;
423
424 filter[4+0] = 0x82;
425 filter[4+0+16] = 0xFF;
426 filter[4+1] = emm_g;
427 filter[4+1+16] = 0x0F;
428
429 filter[36]=SHARED;
430 filter[37]=0;
431 filter[38+0] = 0x82;
432 filter[38+0+16] = 0xFF;
433 filter[38+1] = emm_s;
434 filter[38+1+16] = 0xFF;
435 memcpy(filter+38+2, rdr->hexserial, 2);
436 memset(filter+38+2+16, 0xFF, 2);
437
438 filter[70]=UNIQUE;
439 filter[71]=0;
440 filter[72+0] = 0x82;
441 filter[72+0+16] = 0xFF;
442 filter[72+1] = emm_u;
443 filter[72+1+16] = 0xFF;
444 memcpy(filter+72+2, rdr->hexserial, 3);
445 memset(filter+72+2+16, 0xFF, 3);
446
447 return;
448}
449
450static int irdeto_do_emm(struct s_reader * reader, EMM_PACKET *ep)
451{
452 def_resp;
453 static const uchar sc_EmmCmd[] = { 0x01,0x00,0x00,0x00,0x00 };
454 uchar cta_cmd[272];
455
456 int i, l = (ep->emm[3] & 0x07), ok = 0;
457 int mode = (ep->emm[3] >> 3);
458 uchar *emm = ep->emm;
459
460 if (mode & 0x10) {
461 // hex addressed
462 ok = (mode == reader->hexserial[3] && (!l || !memcmp(&emm[4], reader->hexserial, l)));
463 }
464 else {
465 // not hex addressed and emm mode zero
466 if (mode == 0)
467 ok = 1;
468 else {
469 // provider addressed
470 for(i = 0; i < reader->nprov; i++) {
471 ok = (mode == reader->prid[i][0] && (!l || !memcmp(&emm[4], &reader->prid[i][1], l)));
472 if (ok) break;
473 }
474 }
475 }
476
477 if (ok) {
478 l++;
479 if (l <= ADDRLEN) {
480 const int dataLen = SCT_LEN(emm) - 5 - l; // sizeof of emm bytes (nanos)
481 uchar *ptr = cta_cmd;
482 memcpy(ptr, sc_EmmCmd, sizeof(sc_EmmCmd)); // copy card command
483 ptr[4] = dataLen + ADDRLEN; // set card command emm size
484 ptr += sizeof(sc_EmmCmd); emm += 3;
485 memset(ptr, 0, ADDRLEN); // clear addr range
486 memcpy(ptr, emm, l); // copy addr bytes
487 ptr += ADDRLEN; emm += l;
488 memcpy(ptr, &emm[2], dataLen); // copy emm bytes
489 return(irdeto_do_cmd(reader, cta_cmd, 0, cta_res, &cta_lr) ? 0 : 1);
490 }
491 else
492 cs_debug_mask(D_EMM, "[irdeto-reader] addrlen %d > %d", l, ADDRLEN);
493 }
494 return ERROR;
495}
496
497static int irdeto_card_info(struct s_reader * reader)
498{
499 def_resp;
500 int i, p;
501
502 uchar sc_GetChanelIds[] = { 0x02, 0x04, 0x00, 0x00, 0x01, 0x00 };
503
504 /*
505 * ContryCode2
506 */
507 reader_chk_cmd(sc_GetCountryCode2, 0);
508
509 if ((cta_lr>9) && !(cta_res[cta_lr-2]|cta_res[cta_lr-1]))
510 {
511 cs_debug_mask(D_READER, "[irdeto-reader] max chids: %d, %d, %d, %d", cta_res[6], cta_res[7], cta_res[8], cta_res[9]);
512
513 /*
514 * Provider 2
515 */
516 for (i=p=0; i<reader->nprov; i++)
517 {
518 int j, k, chid, first=1;
519 char t[32];
520 if (reader->prid[i][4]!=0xff)
521 {
522 p++;
523 sc_GetChanelIds[3]=i; // provider at index i
524 j=0;
525 // for (j=0; j<10; j++) => why 10 .. do we know for sure the there are only 10 chids !!!
526 // shouldn't it me the max chid value we read above ?!
527 while(1) // will exit if cta_lr < 61 .. which is the correct break condition.
528 {
529 sc_GetChanelIds[5]=j; // chid at index j for provider at index i
530 reader_chk_cmd(sc_GetChanelIds, 0);
531 // if (cta_lr<61) break; // why 61 (0 to 60 in steps of 6 .. is it 10*6 from the 10 in the for loop ?
532 // what happen if the card only send back.. 9 chids (or less)... we don't see them
533 // so we should check whether or not we have at least 6 bytes (1 chid).
534 if (cta_lr<6) break;
535
536 for(k=0; k<cta_lr; k+=6)
537 {
538 chid=b2i(2, cta_res+k);
539 if (chid && chid!=0xFFFF)
540 {
541 time_t date;
542 chid_date(reader,date=b2i(2, cta_res+k+2), t, 16);
543 chid_date(reader,date+cta_res[k+4], t+16, 16);
544 if (first)
545 {
546 cs_ri_log(reader, "entitlements for provider: %d, id: %06X", p, b2i(3, &reader->prid[i][1]));
547 first=0;
548 }
549 cs_ri_log(reader, "chid: %04X, date: %s - %s", chid, t, t+16);
550 }
551 }
552 j++;
553 }
554 }
555 }
556 }
557 cs_log("[irdeto-reader] ready for requests");
558 return OK;
559}
560
561void reader_irdeto(struct s_cardsystem *ph)
562{
563 ph->do_emm=irdeto_do_emm;
564 ph->do_ecm=irdeto_do_ecm;
565 ph->card_info=irdeto_card_info;
566 ph->card_init=irdeto_card_init;
567 ph->get_emm_type=irdeto_get_emm_type;
568 ph->get_emm_filter=irdeto_get_emm_filter;
569 ph->caids[0]=0x06;
570 ph->caids[1]=0x17;
571 ph->desc="irdeto";
572}
Note: See TracBrowser for help on using the repository browser.