source: trunk/reader-videoguard2.c@ 3182

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

Readers checked on threadsafety except videoguard-common

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