2 #ifdef READER_VIDEOGUARD
3 #include "reader-common.h"
4 #include "reader-videoguard-common.h"
6 static int32_t vg12_do_cmd(struct s_reader
*reader
, const uint8_t *ins
, const uint8_t *txbuff
, uint8_t *rxbuff
, uint8_t *cta_res
)
16 if(!write_cmd_vg(ins2
, NULL
) || !status_ok(cta_res
+ len
))
23 memcpy(rxbuff
, ins2
, 5);
24 memcpy(rxbuff
+ 5, cta_res
, len
);
25 memcpy(rxbuff
+ 5 + len
, cta_res
+ len
, 2);
30 if(!write_cmd_vg(ins2
, (uint8_t *)txbuff
) || !status_ok(cta_res
))
37 memcpy(rxbuff
, ins2
, 5);
38 memcpy(rxbuff
+ 5, txbuff
, len
);
39 memcpy(rxbuff
+ 5 + len
, cta_res
, 2);
45 static void read_tiers(struct s_reader
*reader
)
49 static const uint8_t ins2A
[5] = { 0x48, 0x2A, 0x00, 0x00, 0x90 };
52 if(!write_cmd_vg(ins2A
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
54 rdr_log(reader
, "class48 ins2A: failed");
58 // return at present as not sure how to parse this
61 uint8_t ins76
[5] = { 0x48, 0x76, 0x00, 0x00, 0x00 };
65 if(!write_cmd_vg(ins76
, NULL
) || !status_ok(cta_res
+ 2))
73 int32_t num
= cta_res
[1];
76 cs_clear_entitlement(reader
); // reset the entitlements
78 struct videoguard_data
*csystem_data
= reader
->csystem_data
;
79 for(i
= 0; i
< num
; i
++)
82 l
= vg12_do_cmd(reader
, ins76
, NULL
, NULL
, cta_res
);
84 if(l
< 0 || !status_ok(cta_res
+ l
))
89 if(cta_res
[2] == 0 && cta_res
[3] == 0)
94 uint16_t tier_id
= (cta_res
[2] << 8) | cta_res
[3];
96 memset(&timeinfo
, 0, sizeof(struct tm
));
97 rev_date_calc_tm(&cta_res
[4], &timeinfo
, csystem_data
->card_baseyear
);
98 cs_add_entitlement(reader
, reader
->caid
, b2ll(4, reader
->prid
[0]), tier_id
, 0, 0, mktime(&timeinfo
), 4, 1);
100 rdr_log(reader
, "tier: %04x, expiry date: %04d/%02d/%02d-%02d:%02d:%02d %s",
101 tier_id
, timeinfo
.tm_year
+ 1900, timeinfo
.tm_mon
+ 1, timeinfo
.tm_mday
, timeinfo
.tm_hour
,
102 timeinfo
.tm_min
, timeinfo
.tm_sec
, get_tiername(tier_id
, reader
->caid
, tiername
));
106 static int32_t videoguard12_card_init(struct s_reader
*reader
, ATR
*newatr
)
110 if((hist_size
< 7) || (hist
[1] != 0xB0) || (hist
[4] != 0xFF) || (hist
[5] != 0x4A) || (hist
[6] != 0x50))
112 rdr_log_dbg(reader
, D_READER
, "failed history check");
115 rdr_log_dbg(reader
, D_READER
, "passed history check");
120 if(!cs_malloc(&reader
->csystem_data
, sizeof(struct videoguard_data
)))
124 struct videoguard_data
*csystem_data
= reader
->csystem_data
;
126 /* set information on the card stored in reader-videoguard-common.c */
127 set_known_card_info(reader
, atr
, &atr_size
);
129 if((reader
->ndsversion
!= NDS12
) && ((csystem_data
->card_system_version
!= NDS12
) || (reader
->ndsversion
!= NDSAUTO
)))
131 /* known ATR and not NDS12
132 or unknown ATR and not forced to NDS12
133 or known NDS12 ATR and forced to another NDS version
134 ...probably not NDS12 */
138 rdr_log(reader
, "type: %s, baseyear: %i", csystem_data
->card_desc
, csystem_data
->card_baseyear
);
139 if(reader
->ndsversion
== NDS12
)
141 rdr_log(reader
, "forced to NDS12");
144 /* NDS12 Class 48/49/4A/4B cards only need a very basic initialisation
145 NDS12 Class 48/49/4A/4B cards do not respond to ins7416
146 nor do they return list of valid command therefore do not even try
147 NDS12 Class 48/49/4A/4B cards need to be told the length as (48, ins, 00, 80, 01)
148 does not return the length */
150 static const uint8_t ins4852
[5] = { 0x48, 0x52, 0x00, 0x00, 0x14 };
151 if(!write_cmd_vg(ins4852
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
153 rdr_log(reader
, "class48 ins52: failed");
157 if(!write_cmd_vg(ins4852
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
159 rdr_log(reader
, "class48 ins52: failed");
167 // Try to get the boxid from the card, even if BoxID specified in the config file
168 uint8_t ins36[5] = { 0x48, 0x36, 0x00, 0x00, 0x53 };
170 // get the length of ins36
171 static const uint8_t ins38[5] = { 0x48, 0x38, 0x80, 0x00, 0x02 };
172 if (!write_cmd_vg(ins38,NULL) || !status_ok(cta_res+cta_lr-2)) {
173 rdr_log(reader, "class48 ins38: failed");
176 ins36[3] = cta_res[0];
177 ins36[4] = cta_res[1];
181 if (!write_cmd_vg(ins36,NULL) || !status_ok(cta_res+cta_lr-2)) {
182 rdr_log(reader, "class48 ins36: failed");
186 if (cta_res[2] > 0x0F) {
187 rdr_log(reader, "class48 ins36: encrypted - therefore not an NDS12 card");
190 // skipping the initial fixed fields: encr/rev++ (4)
193 while (i < (cta_lr-2)) {
194 if (!gotUA && cta_res[i] < 0xF0) { // then we guess that the next 4 bytes is the UA
198 switch (cta_res[i]) { // object length vary depending on type
199 case 0x00: // padding
204 case 0xEF: // card status
214 case 0xDF: // next server contact
221 memcpy(&boxID, &cta_res[i + 1], sizeof(boxID));
231 case 0xFC: // No idea NDS1/NDS12
236 case 0x01: // date & time
247 case 0x67: // signature
250 case 0xE9: // tier dates
251 case 0xF8: // Old PPV Event Record
254 i += cta_res[i + 1] + 2; // skip length + 2 bytes (type and length)
257 default: // default to assume a length byte
259 rdr_log(reader, "class48 ins36: returned unknown type=0x%02X - parsing may fail", cta_res[i]);
260 i += cta_res[i + 1] + 2;
267 rdr_log_dbg(reader, D_READER, "calculated BoxID: %02X%02X%02X%02X", boxID[0], boxID[1], boxID[2], boxID[3]);
270 /* the boxid is specified in the config */
271 if(reader
->boxid
> 0)
274 for(i
= 0; i
< 4; i
++)
276 boxID
[i
] = (reader
->boxid
>> (8 * (3 - i
))) % 0x100;
278 rdr_log_dbg(reader
, D_READER
, "oscam.server BoxID: %02X%02X%02X%02X", boxID
[0], boxID
[1], boxID
[2], boxID
[3]);
283 rdr_log(reader
, "no boxID available");
288 static const uint8_t ins484C
[5] = { 0x48, 0x4C, 0x00, 0x00, 0x09 };
289 uint8_t payload4C
[9] = { 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02 };
290 memcpy(payload4C
, boxID
, 4);
291 if(!write_cmd_vg(ins484C
, payload4C
) || !status_ok(cta_res
+ cta_lr
- 2))
293 rdr_log(reader
, "class48 ins4C: sending boxid failed");
297 static const uint8_t ins4858
[5] = { 0x48, 0x58, 0x00, 0x00, 0x35 };
298 if(!write_cmd_vg(ins4858
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
300 rdr_log(reader
, "class48 ins58: failed");
304 memset(reader
->hexserial
, 0, 8);
305 memcpy(reader
->hexserial
+ 2, cta_res
+ 4, 4);
306 memcpy(reader
->sa
, cta_res
+ 4, 3);
307 reader
->caid
= cta_res
[2] * 0x100 + cta_res
[3];
309 /* we have one provider, 0x0000 */
311 memset(reader
->prid
, 0x00, sizeof(reader
->prid
));
313 static const uint8_t insBE
[5] = { 0x4B, 0xBE, 0x00, 0x00, 0x12 };
314 if(!write_cmd_vg(insBE
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
316 rdr_log(reader
, "class4B ins52: failed");
320 static const uint8_t ins4952
[5] = { 0x49, 0x52, 0x00, 0x00, 0x14 };
321 if(!write_cmd_vg(ins4952
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
323 rdr_log(reader
, "class49 ins52: failed");
327 static const uint8_t ins4958
[5] = { 0x49, 0x58, 0x00, 0x00, 0x35 };
328 if(!write_cmd_vg(ins4958
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
330 rdr_log(reader
, "class49 ins58: failed");
334 // Send BoxID class 49
335 static const uint8_t ins494C
[5] = { 0x49, 0x4C, 0x00, 0x00, 0x09 };
336 if(!write_cmd_vg(ins494C
, payload4C
) || !status_ok(cta_res
+ cta_lr
- 2))
338 rdr_log(reader
, "class49 ins4C: sending boxid failed");
342 static const uint8_t ins0C
[5] = { 0x49, 0x0C, 0x00, 0x00, 0x0A };
343 if(!write_cmd_vg(ins0C
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
345 rdr_log(reader
, "class49 ins0C: failed");
349 rdr_log_sensitive(reader
, "type: VideoGuard, caid: %04X, serial: {%02X%02X%02X%02X}, BoxID: {%02X%02X%02X%02X}",
350 reader
->caid
, reader
->hexserial
[2], reader
->hexserial
[3], reader
->hexserial
[4],
351 reader
->hexserial
[5], boxID
[0], boxID
[1], boxID
[2], boxID
[3]);
352 rdr_log(reader
, "ready for requests - this is in testing please send -d 255 logs to rebdog");
357 static int32_t videoguard12_do_ecm(struct s_reader
*reader
, const ECM_REQUEST
*er
, struct s_ecm_answer
*ea
)
359 uint8_t cta_res
[CTA_RES_LEN
];
360 uint8_t ins40
[5] = { 0x49, 0x40, 0x40, 0x80, 0xFF };
361 static const uint8_t ins54
[5] = { 0x4B, 0x54, 0x00, 0x00, 0x17 };
362 int32_t posECMpart2
= er
->ecm
[6] + 7;
363 int32_t lenECMpart2
= er
->ecm
[posECMpart2
];
367 memcpy(&tbuff
[0], &(er
->ecm
[posECMpart2
+ 1]), lenECMpart2
);
368 ins40
[4] = lenECMpart2
;
371 l
= vg12_do_cmd(reader
, ins40
, tbuff
, NULL
, cta_res
);
372 if(l
> 0 && status_ok(cta_res
))
374 l
= vg12_do_cmd(reader
, ins54
, NULL
, rbuff
, cta_res
);
375 if(l
> 0 && status_ok(cta_res
+ l
))
377 if(!cw_is_valid(rbuff
+ 5)) // sky cards report 90 00 = ok but send cw = 00 when channel not subscribed
379 rdr_log(reader
, "class4B ins54 status 90 00 but cw=00 -> channel not subscribed");
385 memset(ea
->cw
+ 0, 0, 8);
386 memcpy(ea
->cw
+ 8, rbuff
+ 5, 8);
390 memcpy(ea
->cw
+ 0, rbuff
+ 5, 8);
391 memset(ea
->cw
+ 8, 0, 8);
396 rdr_log(reader
, "class4B ins54 (%d) status not ok %02x %02x", l
, cta_res
[0], cta_res
[1]);
400 static int32_t videoguard12_do_emm(struct s_reader
*reader
, EMM_PACKET
*ep
)
402 return videoguard_do_emm(reader
, ep
, 0x49, read_tiers
, vg12_do_cmd
);
405 static int32_t videoguard12_do_rawcmd(struct s_reader
*reader
, CMD_PACKET
*cp
)
407 return videoguard_do_rawcmd(reader
, cp
);
410 static int32_t videoguard12_card_info(struct s_reader
*reader
)
412 /* info is displayed in init, or when processing info */
413 struct videoguard_data
*csystem_data
= reader
->csystem_data
;
414 rdr_log(reader
, "card detected");
415 rdr_log(reader
, "type: %s", csystem_data
->card_desc
);
420 const struct s_cardsystem reader_videoguard12
=
422 .desc
= "videoguard12",
423 .caids
= (uint16_t[]){ 0x09, 0 },
424 .do_emm
= videoguard12_do_emm
,
425 .do_rawcmd
= videoguard12_do_rawcmd
,
426 .do_ecm
= videoguard12_do_ecm
,
427 .card_info
= videoguard12_card_info
,
428 .card_init
= videoguard12_card_init
,
429 .get_emm_type
= videoguard_get_emm_type
,
430 .get_emm_filter
= videoguard_get_emm_filter
,