source: trunk/reader-videoguard2.c@ 3181

Last change on this file since 3181 was 3181, checked in by dingo35, 10 years ago

Adding threadsafety FIXMEs, feel free to join checking..

File size: 18.1 KB
Line 
1//FIXME Not checked on threadsafety yet; after checking please remove this line
2#include "globals.h"
3#include "reader-common.h"
4#include "reader-videoguard-common.h"
5
6
7static void vg2_read_tiers(struct s_reader * reader)
8{
9 def_resp;
10 int l;
11
12 /* ins2a is not needed and causes an error on some cards eg Sky Italy 09CD
13 check if ins2a is in command table before running it
14 */
15 static const unsigned char ins2a[5] = { 0xD0,0x2a,0x00,0x00,0x00 };
16 if(cmd_exists(ins2a)) {
17 l=do_cmd(reader,ins2a,NULL,NULL,NULL,cta_res);
18 if(l<0 || !status_ok(cta_res+l)){
19 cs_log ("[videoguard2-reader] classD0 ins2a: failed");
20 return;
21 }
22 }
23
24 static unsigned char ins76007f[5] = { 0xD0,0x76,0x00,0x7f,0x02 };
25 if(!write_cmd_vg(ins76007f,NULL) || !status_ok(cta_res+2)){
26 cs_log ("[videoguard2-reader] classD0 ins76007f: failed");
27 return;
28 }
29 int num=cta_res[1];
30
31 int i;
32 static unsigned char ins76[5] = { 0xD0,0x76,0x00,0x00,0x00 };
33#ifdef CS_RDR_INIT_HIST
34 reader->init_history_pos = 0; //reset for re-read
35 memset(reader->init_history, 0, sizeof(reader->init_history));
36#endif
37 for(i=0; i<num; i++) {
38 ins76[2]=i;
39 l=do_cmd(reader,ins76,NULL,NULL,NULL,cta_res);
40 if(l<0 || !status_ok(cta_res+l)) return;
41 if(cta_res[2]==0 && cta_res[3]==0) break;
42 int y,m,d,H,M,S;
43 rev_date_calc(&cta_res[4],&y,&m,&d,&H,&M,&S,reader->card_baseyear);
44 unsigned short tier_id = (cta_res[2] << 8) | cta_res[3];
45 char *tier_name = get_tiername(tier_id, reader->caid[0]);
46 cs_ri_log(reader, "[videoguard2-reader] tier: %04x, expiry date: %04d/%02d/%02d-%02d:%02d:%02d %s",tier_id,y,m,d,H,M,S,tier_name);
47 }
48}
49
50int videoguard2_card_init(struct s_reader * reader, ATR newatr)
51{
52 get_hist;
53 if ((hist_size < 7) || (hist[1] != 0xB0) || (hist[4] != 0xFF) || (hist[5] != 0x4A) || (hist[6] != 0x50))
54 return ERROR;
55
56 get_atr;
57 def_resp;
58
59 // Copy the atr info into the reader, can we not do this in reader-common.c?
60 reader->atrlen = atr_size;
61 memcpy(reader->atr,atr,atr_size);
62
63 /* set information on the card stored in reader-videoguard-common.c */
64 set_known_card_info(reader);
65
66 if((reader->ndsversion != NDS2) &&
67 (((reader->card_system_version != NDS2) && (reader->card_system_version != NDSUNKNOWN)) ||
68 (reader->ndsversion != NDSAUTO))) {
69 /* known ATR and not NDS2
70 or known NDS2 ATR and forced to another NDS version */
71 return ERROR;
72 }
73
74 cs_ri_log(reader, "[videoguard2-reader] type: %s, baseyear: %i", reader->card_desc, reader->card_baseyear);
75 if(reader->ndsversion == NDS2){
76 cs_log("[videoguard2-reader] forced to NDS2");
77 }
78
79 //a non videoguard2/NDS2 card will fail on read_cmd_len(ins7401)
80 //this way unknown videoguard2/NDS2 cards will also pass this check
81
82 unsigned char ins7401[5] = { 0xD0,0x74,0x01,0x00,0x00 };
83 int l;
84 ins7401[3]=0x80; // from newcs log
85 ins7401[4]=0x01;
86 if((l=read_cmd_len(reader, ins7401))<0) return ERROR; //not a videoguard2/NDS card or communication error
87 ins7401[3]=0x00;
88 ins7401[4]=l;
89 if(!write_cmd_vg(ins7401,NULL) || !status_ok(cta_res+l)) {
90 cs_log ("[videoguard2-reader] classD0 ins7401: failed - cmd list not read");
91 return ERROR;
92 }
93
94 memorize_cmd_table (cta_res,l);
95
96 unsigned char buff[256];
97
98 unsigned char ins7416[5] = { 0xD0,0x74,0x16,0x00,0x00 };
99 if(do_cmd(reader,ins7416,NULL,NULL,NULL,cta_res)<0) {
100 cs_log ("[videoguard2-reader] classD0 ins7416: failed");
101 return ERROR;
102 }
103
104 unsigned char ins36[5] = { 0xD0,0x36,0x00,0x00,0x00 };
105 unsigned char ins5e[5] = { 0xD0,0x5E,0x00,0x0C,0x02 };
106 unsigned char boxID [4];
107
108 if (reader->boxid > 0) {
109 /* the boxid is specified in the config */
110 int i;
111 for (i=0; i < 4; i++) {
112 boxID[i] = (reader->boxid >> (8 * (3 - i))) % 0x100;
113 }
114 } else {
115 /* we can try to get the boxid from the card */
116 int boxidOK=0;
117 if((ins36[4]=read_cmd_len(reader, ins36))==0 && cmd_exists(ins5e)) {
118 if(!write_cmd_vg(ins5e,NULL) || !status_ok(cta_res+2)){
119 cs_log ("[videoguard2-reader] classD0 ins5e: failed");
120 } else {
121 ins36[3] = cta_res[0];
122 ins36[4] = cta_res[1];
123 }
124 }
125 l=ins36[4];
126 if(!write_cmd_vg(ins36,NULL) || !status_ok(cta_res+l)){
127 cs_log ("[videoguard2-reader] classD0 ins36: failed");
128 return ERROR;
129 }
130 memcpy(buff,ins36,5);
131 memcpy(buff+5,cta_res,l);
132 memcpy(buff+5+l,cta_res+l,2);
133 if(l<13)
134 cs_log("[videoguard2-reader] classD0 ins36: too short answer");
135 else if (buff[7] > 0x0F)
136 cs_log("[videoguard2-reader] classD0 ins36: encrypted - can't parse");
137 else {
138 /* skipping the initial fixed fields: cmdecho (4) + length (1) + encr/rev++ (4) */
139 int i=9;
140 int gotUA=0;
141 while (i<l) {
142 if (!gotUA && buff[i]<0xF0) { /* then we guess that the next 4 bytes is the UA */
143 gotUA=1;
144 i+=4;
145 } else switch (buff[i]) { /* object length vary depending on type */
146 case 0x00: /* padding */
147 i+=1;
148 break;
149 case 0xEF: /* card status */
150 i+=3;
151 break;
152 case 0xD1:
153 i+=4;
154 break;
155 case 0xDF: /* next server contact */
156 i+=5;
157 break;
158 case 0xF3: /* boxID */
159 memcpy(boxID,buff+i+1,sizeof(boxID));
160 boxidOK=1;
161 i+=5;
162 break;
163 case 0xF6:
164 i+=6;
165 break;
166 case 0x01: /* date & time */
167 i+=7;
168 break;
169 case 0xFA:
170 i+=9;
171 break;
172 case 0x5E:
173 case 0x67: /* signature */
174 case 0xDE:
175 case 0xE2:
176 case 0xE9: /* tier dates */
177 case 0xF8: /* Old PPV Event Record */
178 case 0xFD:
179 i+=buff[i+1]+2; /* skip length + 2 bytes (type and length) */
180 break;
181 default: /* default to assume a length byte */
182 cs_log("[videoguard2-reader] classD0 ins36: returned unknown type=0x%02X - parsing may fail", buff[i]);
183 i+=buff[i+1]+2;
184 }
185 }
186 }
187
188 if(!boxidOK) {
189 cs_log ("[videoguard2-reader] no boxID available");
190 return ERROR;
191 }
192 }
193
194 unsigned char ins4C[5] = { 0xD0,0x4C,0x00,0x00,0x09 };
195 unsigned char payload4C[9] = { 0,0,0,0, 3,0,0,0,4 };
196 memcpy(payload4C,boxID,4);
197 if(!write_cmd_vg(ins4C,payload4C) || !status_ok(cta_res+l)) {
198 cs_log("[videoguard2-reader] classD0 ins4C: failed - sending boxid failed");
199 return ERROR;
200 }
201
202 //short int SWIRDstatus = cta_res[1];
203 unsigned char ins58[5] = { 0xD0,0x58,0x00,0x00,0x00 };
204 l=do_cmd(reader,ins58,NULL,buff,NULL,cta_res);
205 if(l<0) {
206 cs_log("[videoguard2-reader] classD0 ins58: failed");
207 return ERROR;
208 }
209 memset(reader->hexserial, 0, 8);
210 memcpy(reader->hexserial+2, cta_res+3, 4);
211 memcpy(reader->sa, cta_res+3, 3);
212 reader->caid[0] = cta_res[24]*0x100+cta_res[25];
213
214 /* we have one provider, 0x0000 */
215 reader->nprov = 1;
216 memset(reader->prid, 0x00, sizeof(reader->prid));
217
218 /*
219 cs_log ("[videoguard2-reader] INS58 : Fuse byte=0x%02X, IRDStatus=0x%02X", cta_res[2],SWIRDstatus);
220 if (SWIRDstatus==4) {
221 // If swMarriage=4, not married then exchange for BC Key
222 cs_log ("[videoguard2-reader] Card not married, exchange for BC Keys");
223 */
224
225 unsigned char seed1[] = {
226 0xb9, 0xd5, 0xef, 0xd5, 0xf5, 0xd5, 0xfb, 0xd5, 0x31, 0xd6, 0x43, 0xd6, 0x55, 0xd6, 0x61, 0xd6,
227 0x85, 0xd6, 0x9d, 0xd6, 0xaf, 0xd6, 0xc7, 0xd6, 0xd9, 0xd6, 0x09, 0xd7, 0x15, 0xd7, 0x21, 0xd7,
228 0x27, 0xd7, 0x3f, 0xd7, 0x45, 0xd7, 0xb1, 0xd7, 0xbd, 0xd7, 0xdb, 0xd7, 0x11, 0xd8, 0x23, 0xd8,
229 0x29, 0xd8, 0x2f, 0xd8, 0x4d, 0xd8, 0x8f, 0xd8, 0xa1, 0xd8, 0xad, 0xd8, 0xbf, 0xd8, 0xd7, 0xd8
230 };
231 unsigned char seed2[] = {
232 0x01, 0x00, 0xcf, 0x13, 0xe0, 0x60, 0x54, 0xac, 0xab, 0x99, 0xe6, 0x0c, 0x9f, 0x5b, 0x91, 0xb9,
233 0x72, 0x72, 0x4d, 0x5b, 0x5f, 0xd3, 0xb7, 0x5b, 0x01, 0x4d, 0xef, 0x9e, 0x6b, 0x8a, 0xb9, 0xd1,
234 0xc9, 0x9f, 0xa1, 0x2a, 0x8d, 0x86, 0xb6, 0xd6, 0x39, 0xb4, 0x64, 0x65, 0x13, 0x77, 0xa1, 0x0a,
235 0x0c, 0xcf, 0xb4, 0x2b, 0x3a, 0x2f, 0xd2, 0x09, 0x92, 0x15, 0x40, 0x47, 0x66, 0x5c, 0xda, 0xc9
236 };
237
238 cCamCryptVG_SetSeed(seed1,seed2);
239
240 unsigned char insB4[5] = { 0xD0,0xB4,0x00,0x00,0x40 };
241 unsigned char tbuff[64];
242 cCamCryptVG_GetCamKey(tbuff);
243 l=do_cmd(reader,insB4,tbuff,NULL,NULL,cta_res);
244 if(l<0 || !status_ok(cta_res)) {
245 cs_log ("[videoguard2-reader] classD0 insB4: failed (%02X%02X)", cta_res[0], cta_res[1]);
246 return ERROR;
247 }
248
249 unsigned char insBC[5] = { 0xD0,0xBC,0x00,0x00,0x00 };
250 l=do_cmd(reader,insBC,NULL,NULL,NULL,cta_res);
251 if(l<0) {
252 cs_log("[videoguard2-reader] classD0 insBC: failed");
253 return ERROR;
254 }
255
256 unsigned char insBE[5] = { 0xD3,0xBE,0x00,0x00,0x00 };
257 l=do_cmd(reader,insBE,NULL,NULL,NULL,cta_res);
258 if(l<0) {
259 cs_log("[videoguard2-reader] classD3 insBE: failed");
260 return ERROR;
261 }
262
263 unsigned char ins58a[5] = { 0xD1,0x58,0x00,0x00,0x00 };
264 l=do_cmd(reader,ins58a,NULL,NULL,NULL,cta_res);
265 if(l<0) {
266 cs_log("[videoguard2-reader] classD1 ins58: failed");
267 return ERROR;
268 }
269
270 unsigned char ins4Ca[5] = { 0xD1,0x4C,0x00,0x00,0x00 };
271 l=do_cmd(reader,ins4Ca,payload4C,NULL,NULL,cta_res);
272 if(l<0 || !status_ok(cta_res)) {
273 cs_log("[videoguard2-reader] classD1 ins4Ca: failed");
274 return ERROR;
275 }
276
277 // fix for 09ac cards
278 unsigned char dimeno_magic[0x10]={0xF9,0xFB,0xCD,0x5A,0x76,0xB5,0xC4,0x5C,0xC8,0x2E,0x1D,0xE1,0xCC,0x5B,0x6B,0x02};
279 int a;
280 for(a=0; a<4; a++)
281 dimeno_magic[a]=dimeno_magic[a]^boxID[a];
282 add_aes_entry(reader, reader->caid[0], 0, AESKEY_ASTRO, dimeno_magic);
283
284 AES_ENTRY *current;
285 current=reader->aes_list;
286 while(current) {
287 cs_log("**************************");
288 cs_log("current = %p",current);
289 cs_log("CAID = %04x",current->caid);
290 cs_log("IDENT = %06x",current->ident);
291 cs_log("keyID = %d",current->keyid);
292 cs_log("next = %p",current->next);
293 cs_log("**************************");
294 current=current->next;
295 }
296
297 cs_ri_log(reader, "[videoguard2-reader] type: %s, caid: %04X, serial: %02X%02X%02X%02X, BoxID: %02X%02X%02X%02X",
298 reader->card_desc,
299 reader->caid[0],
300 reader->hexserial[2],reader->hexserial[3],reader->hexserial[4],reader->hexserial[5],
301 boxID[0],boxID[1],boxID[2],boxID[3]);
302
303 cs_log("[videoguard2-reader] ready for requests");
304
305 return OK;
306}
307
308int videoguard2_do_ecm(struct s_reader * reader, ECM_REQUEST *er)
309{
310 unsigned char cta_res[CTA_RES_LEN];
311 static unsigned char ins40[5] = { 0xD1,0x40,0x00,0x80,0xFF };
312 static const unsigned char ins54[5] = { 0xD3,0x54,0x00,0x00,0x00};
313 int posECMpart2=er->ecm[6]+7;
314 int lenECMpart2=er->ecm[posECMpart2]+1;
315 unsigned char tbuff[264];
316 tbuff[0]=0;
317 memcpy(tbuff+1,er->ecm+posECMpart2+1,lenECMpart2-1);
318 ins40[4]=lenECMpart2;
319 int l;
320 l = do_cmd(reader,ins40,tbuff,NULL,NULL,cta_res);
321 if(l>0 && status_ok(cta_res)) {
322 l = do_cmd(reader,ins54,NULL,NULL,er->cw,cta_res);
323 if(l>0 && status_ok(cta_res+l)) {
324 if (!cw_is_valid(er->cw+0,0)) //sky cards report 90 00 = ok but send cw = 00 when channel not subscribed
325 {
326 cs_log("[reader-videoguard2] classD3 ins54: status 90 00 but cw=00 -> channel not subscribed " );
327 return ERROR;
328 }
329
330 if(er->ecm[0]&1) {
331 unsigned char tmpcw[8];
332 memcpy(tmpcw,er->cw+8,8);
333 memcpy(er->cw+8,er->cw+0,8);
334 memcpy(er->cw+0,tmpcw,8);
335 }
336
337 //test for postprocessing marker
338 int posB0 = -1;
339 int i;
340 for (i = 6; i < posECMpart2; i++)
341 {
342 if (er->ecm[i-3] == 0x80 && er->ecm[i] == 0xB0 && ((er->ecm[i+1] == 0x01) ||(er->ecm[i+1] == 0x02)||(er->ecm[i+1] == 0x03) ) ) {
343 posB0 = i;
344 break;
345 }
346 }
347
348 if (posB0 != -1) {
349 do_post_dw_hash( er->cw+0, &er->ecm[posB0-2]);
350 do_post_dw_hash( er->cw+8, &er->ecm[posB0-2]);
351 }
352
353 return OK;
354 }
355 }
356 cs_log("[reader-videoguard2] classD3 ins54: (%d) status not ok %02x %02x",l, cta_res[0],cta_res[1] );
357 return ERROR;
358}
359
360static int num_addr(const unsigned char *data)
361{
362 return ((data[3]&0x30)>>4)+1;
363}
364/*
365Example of GLOBAL EMM's
366This one has IRD-EMM + Card-EMM
36782 70 20 00 02 06 02 7D 0E 89 53 71 16 90 14 40
36801 ED 17 7D 9E 1F 28 CF 09 97 54 F1 8E 72 06 E7
36951 AF F5
370This one has only IRD-EMM
37182 70 6D 00 07 69 01 30 07 14 5E 0F FF FF 00 06
37200 0D 01 00 03 01 00 00 00 0F 00 00 00 5E 01 00
37301 0C 2E 70 E4 55 B6 D2 34 F7 44 86 9E 5C 91 14
37481 FC DF CB D0 86 65 77 DF A9 E1 6B A8 9F 9B DE
37590 92 B9 AA 6C B3 4E 87 D2 EC 92 DA FC 71 EF 27
376B3 C3 D0 17 CF 0B D6 5E 8C DB EB B3 37 55 6E 09
3777F 27 3C F1 85 29 C9 4E 0B EE DF 68 BE 00 C9 00
378*/
379static const unsigned char *payload_addr(uchar emmtype, const unsigned char *data, const unsigned char *a)
380{
381 int s;
382 int l;
383 const unsigned char *ptr = NULL;
384 int position=-1;
385 int numAddrs=0;
386
387 switch(emmtype) {
388 case SHARED: s=3; break;
389 case UNIQUE: s=4; break;
390 default: s=0;
391 }
392
393 numAddrs=num_addr(data);
394
395 if(s>0) {
396 for(l=0;l<numAddrs;l++) {
397 if(!memcmp(&data[l*4+4],a+2,s)) {
398 position=l;
399 break;
400 }
401 }
402 }
403
404 int num_filter = (position == -1) ? 0 : numAddrs;
405
406 /* skip header and the filter list */
407 ptr = data+4+4*num_filter;
408
409 if (*ptr != 0x02 && *ptr != 0x07) // some clients omit 00 00 separator */
410 {
411 ptr += 2; // skip 00 00 separator
412 if (*ptr == 0x00) ptr++; // skip optional 00
413 ptr++; // skip the 1st bitmap len
414 }
415
416 /* check for IRD-EMM */
417 if (*ptr != 0x02 && *ptr != 0x07) return NULL;
418
419 /* skip IRD-EMM part, 02 00 or 02 06 xx aabbccdd yy */
420 ptr += 2 + ptr[1];
421
422 /* check for EMM boundaries - ptr should not exceed EMM length */
423 if ((int)(ptr - (data + 3)) >= data[2]) return NULL;
424
425 for(l=0;l<position;l++) {
426 /* skip the payload of the previous sub-EMM */
427 ptr += 1 + ptr [0];
428
429 /* check for EMM boundaries - ptr should not exceed EMM length */
430 if ((int)(ptr - (data + 3)) >= data[2]) return NULL;
431
432 /* skip optional 00 */
433 if (*ptr == 0x00) ptr++;
434
435 /* skip the bitmap len */
436 ptr++;
437
438 /* check for IRD-EMM */
439 if (*ptr != 0x02 && *ptr != 0x07) return NULL;
440
441 /* skip IRD-EMM part, 02 00 or 02 06 xx aabbccdd yy */
442 ptr += 2 + ptr[1];
443 }
444
445 return ptr;
446}
447
448int videoguard2_get_emm_type(EMM_PACKET *ep, struct s_reader * rdr)
449{
450
451/*
45282 30 ad 70 00 XX XX XX 00 XX XX XX 00 XX XX XX 00 XX XX XX 00 00
453d3 02 00 22 90 20 44 02 4a 50 1d 88 ab 02 ac 79 16 6c df a1 b1 b7 77 00 ba eb 63 b5 c9 a9 30 2b 43 e9 16 a9 d5 14 00
454d3 02 00 22 90 20 44 02 13 e3 40 bd 29 e4 90 97 c3 aa 93 db 8d f5 6b e4 92 dd 00 9b 51 03 c9 3d d0 e2 37 44 d3 bf 00
455d3 02 00 22 90 20 44 02 97 79 5d 18 96 5f 3a 67 70 55 bb b9 d2 49 31 bd 18 17 2a e9 6f eb d8 76 ec c3 c9 cc 53 39 00
456d2 02 00 21 90 1f 44 02 99 6d df 36 54 9c 7c 78 1b 21 54 d9 d4 9f c1 80 3c 46 10 76 aa 75 ef d6 82 27 2e 44 7b 00
457*/
458
459 int i, pos;
460 int serial_count = ((ep->emm[3] >> 4) & 3) + 1;
461 int serial_len = (ep->emm[3] & 0x80) ? 3 : 4;
462 uchar emmtype = (ep->emm[3] & VG_EMMTYPE_MASK) >> 6;
463
464 pos = 4 + (serial_len * serial_count) + 2;
465
466 switch(emmtype) {
467 case VG_EMMTYPE_G:
468 ep->type=GLOBAL;
469 cs_debug_mask(D_EMM, "VIDEOGUARD2 EMM: GLOBAL");
470 return TRUE;
471
472 case VG_EMMTYPE_U:
473 cs_debug_mask(D_EMM, "VIDEOGUARD2 EMM: UNIQUE");
474 ep->type=UNIQUE;
475 if (ep->emm[1] == 0) // detected UNIQUE EMM from cccam (there is no serial)
476 return TRUE;
477
478 for (i = 1;i <= serial_count;i++) {
479 if (!memcmp (rdr->hexserial + 2, ep->emm + (serial_len * i), serial_len)) {
480 memcpy(ep->hexserial, ep->emm + (serial_len * i), serial_len);
481 return TRUE;
482 }
483
484 pos = pos + ep->emm[pos+5] + 5;
485 }
486 return FALSE; // if UNIQUE but no serial match return FALSE
487
488 case VG_EMMTYPE_S:
489 ep->type=SHARED;
490 cs_debug_mask(D_EMM, "VIDEOGUARD2 EMM: SHARED");
491 return TRUE; // FIXME: no check for SA
492
493 default:
494 if (ep->emm[pos-2] != 0x00 && ep->emm[pos-1] != 0x00 && ep->emm[pos-1] != 0x01) {
495 //remote emm without serial
496 ep->type=UNKNOWN;
497 return TRUE;
498 }
499 return FALSE;
500 }
501}
502
503void videoguard2_get_emm_filter(struct s_reader * rdr, uchar *filter)
504{
505 filter[0]=0xFF;
506 filter[1]=3;
507
508 //ToDo videoguard2_get_emm_filter basic construction
509
510 filter[2]=UNIQUE;
511 filter[3]=0;
512
513 filter[4+0] = 0x82;
514 filter[4+0+16] = 0xFF;
515
516 memcpy(filter+4+2, rdr->hexserial+2, 4);
517 memset(filter+4+2+16, 0xFF, 4);
518
519 filter[36]=UNIQUE;
520 filter[37]=0;
521
522 filter[38+0] = 0x82;
523 filter[38+0+16] = 0xFF;
524
525 memcpy(filter+38+6, rdr->hexserial+2, 4);
526 memset(filter+38+6+16, 0xFF, 4);
527
528 filter[70]=UNIQUE;
529 filter[71]=0;
530
531 filter[72+0] = 0x82;
532 filter[72+0+16] = 0xFF;
533
534 memcpy(filter+72+10, rdr->hexserial+2, 4);
535 memset(filter+72+10+16, 0xFF, 4);
536
537 /* filter[104]=UNIQUE;
538 filter[105]=0;
539
540 filter[106+0] = 0x82;
541 filter[106+0+16] = 0xFF;
542
543 memcpy(filter+106+14, rdr->hexserial+2, 2);
544 memset(filter+106+14+16, 0xFF, 2); */
545
546 return;
547}
548
549int videoguard2_do_emm(struct s_reader * reader, EMM_PACKET *ep)
550{
551 unsigned char cta_res[CTA_RES_LEN];
552 unsigned char ins42[5] = { 0xD1,0x42,0x00,0x00,0xFF };
553 int rc=ERROR;
554
555 const unsigned char *payload = payload_addr(ep->type, ep->emm, reader->hexserial);
556 while (payload) {
557 ins42[4]=*payload;
558 int l = do_cmd(reader,ins42,payload+1,NULL,NULL,cta_res);
559 if(l>0 && status_ok(cta_res)) {
560 rc=OK;
561 }
562
563 cs_debug_mask(D_EMM, "[videoguard2-reader] EMM request return code : %02X%02X", cta_res[0], cta_res[1]);
564 //cs_dump(ep->emm, 64, "EMM:");
565 if (status_ok (cta_res) && (cta_res[1] & 0x01)) {
566 vg2_read_tiers(reader);
567 }
568
569 if (num_addr(ep->emm) == 1 && (int)(&payload[1] - &ep->emm[0]) + *payload + 1 < ep->l) {
570 payload += *payload + 1;
571 if (*payload == 0x00) ++payload;
572 ++payload;
573 if (*payload != 0x02) break;
574 payload += 2 + payload[1];
575 }
576 else
577 payload = 0;
578
579 }
580
581 return(rc);
582}
583
584int videoguard2_card_info(struct s_reader * reader)
585{
586 /* info is displayed in init, or when processing info */
587 cs_log("[videoguard2-reader] card detected");
588 cs_log("[videoguard2-reader] type: %s", reader->card_desc );
589 vg2_read_tiers (reader);
590 return OK;
591}
592
593void reader_videoguard2(struct s_cardsystem *ph)
594{
595 ph->do_emm=videoguard2_do_emm;
596 ph->do_ecm=videoguard2_do_ecm;
597 ph->card_info=videoguard2_card_info;
598 ph->card_init=videoguard2_card_init;
599 ph->get_emm_type=videoguard2_get_emm_type;
600 ph->caids[0]=0x09;
601}
Note: See TracBrowser for help on using the repository browser.