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 unsigned char *ins
, const unsigned char *txbuff
, unsigned char *rxbuff
, unsigned char *cta_res
)
11 unsigned char len
= 0;
17 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
, (uchar
*) txbuff
) || !status_ok(cta_res
))
36 memcpy(rxbuff
, ins2
, 5);
37 memcpy(rxbuff
+ 5, txbuff
, len
);
38 memcpy(rxbuff
+ 5 + len
, cta_res
, 2);
44 static void read_tiers(struct s_reader
*reader
)
48 static const unsigned char ins2A
[5] = { 0x48, 0x2A, 0x00, 0x00, 0x90 };
51 if(!write_cmd_vg(ins2A
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
53 rdr_log(reader
, "class48 ins2A: failed");
57 // return at present as not sure how to parse this
60 unsigned char ins76
[5] = { 0x48, 0x76, 0x00, 0x00, 0x00 };
63 if(!write_cmd_vg(ins76
, NULL
) || !status_ok(cta_res
+ 2))
69 int32_t num
= cta_res
[1];
72 cs_clear_entitlement(reader
); //reset the entitlements
74 struct videoguard_data
*csystem_data
= reader
->csystem_data
;
75 for(i
= 0; i
< num
; i
++)
78 l
= vg12_do_cmd(reader
, ins76
, NULL
, NULL
, cta_res
);
79 if(l
< 0 || !status_ok(cta_res
+ l
))
83 if(cta_res
[2] == 0 && cta_res
[3] == 0)
87 uint16_t tier_id
= (cta_res
[2] << 8) | cta_res
[3];
89 memset(&timeinfo
, 0, sizeof(struct tm
));
90 rev_date_calc_tm(&cta_res
[4], &timeinfo
, csystem_data
->card_baseyear
);
91 cs_add_entitlement(reader
, reader
->caid
, b2ll(4, reader
->prid
[0]), tier_id
, 0, 0, mktime(&timeinfo
), 4, 1);
93 rdr_log(reader
, "tier: %04x, expiry date: %04d/%02d/%02d-%02d:%02d:%02d %s", tier_id
, timeinfo
.tm_year
+ 1900, timeinfo
.tm_mon
+ 1, timeinfo
.tm_mday
, timeinfo
.tm_hour
, timeinfo
.tm_min
, timeinfo
.tm_sec
, get_tiername(tier_id
, reader
->caid
, tiername
));
97 static int32_t videoguard12_card_init(struct s_reader
*reader
, ATR
*newatr
)
102 if((hist_size
< 7) || (hist
[1] != 0xB0) || (hist
[4] != 0xFF) || (hist
[5] != 0x4A) || (hist
[6] != 0x50))
104 rdr_log_dbg(reader
, D_READER
, "failed history check");
107 rdr_log_dbg(reader
, D_READER
, "passed history check");
112 if(!cs_malloc(&reader
->csystem_data
, sizeof(struct videoguard_data
)))
114 struct videoguard_data
*csystem_data
= reader
->csystem_data
;
116 /* set information on the card stored in reader-videoguard-common.c */
117 set_known_card_info(reader
, atr
, &atr_size
);
119 if((reader
->ndsversion
!= NDS12
) && ((csystem_data
->card_system_version
!= NDS12
) || (reader
->ndsversion
!= NDSAUTO
)))
121 /* known ATR and not NDS12
122 or unknown ATR and not forced to NDS12
123 or known NDS12 ATR and forced to another NDS version
124 ... probably not NDS12 */
128 rdr_log(reader
, "type: %s, baseyear: %i", csystem_data
->card_desc
, csystem_data
->card_baseyear
);
129 if(reader
->ndsversion
== NDS12
)
131 rdr_log(reader
, "forced to NDS12");
134 /* NDS12 Class 48/49/4A/4B cards only need a very basic initialisation
135 NDS12 Class 48/49/4A/4B cards do not respond to ins7416
136 nor do they return list of valid command therefore do not even try
137 NDS12 Class 48/49/4A/4B cards need to be told the length as (48, ins, 00, 80, 01)
138 does not return the length */
140 static const unsigned char ins4852
[5] = { 0x48, 0x52, 0x00, 0x00, 0x14 };
141 if(!write_cmd_vg(ins4852
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
143 rdr_log(reader
, "class48 ins52: failed");
146 if(!write_cmd_vg(ins4852
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
148 rdr_log(reader
, "class48 ins52: failed");
152 unsigned char boxID
[4];
156 // Try to get the boxid from the card, even if BoxID specified in the config file
157 unsigned char ins36[5] = { 0x48, 0x36, 0x00, 0x00, 0x53 };
159 // get the length of ins36
160 static const unsigned char ins38[5] = { 0x48, 0x38, 0x80, 0x00, 0x02 };
161 if (!write_cmd_vg(ins38,NULL) || !status_ok(cta_res+cta_lr-2)) {
162 rdr_log(reader, "class48 ins38: failed");
165 ins36[3] = cta_res[0];
166 ins36[4] = cta_res[1];
170 if (!write_cmd_vg(ins36,NULL) || !status_ok(cta_res+cta_lr-2)) {
171 rdr_log(reader, "class48 ins36: failed");
175 if (cta_res[2] > 0x0F) {
176 rdr_log(reader, "class48 ins36: encrypted - therefore not an NDS12 card");
179 // skipping the initial fixed fields: encr/rev++ (4)
182 while (i < (cta_lr-2)) {
183 if (!gotUA && cta_res[i] < 0xF0) { // then we guess that the next 4 bytes is the UA
187 switch (cta_res[i]) { // object length vary depending on type
188 case 0x00: // padding
193 case 0xEF: // card status
203 case 0xDF: // next server contact
210 memcpy(&boxID, &cta_res[i + 1], sizeof(boxID));
220 case 0xFC: // No idea NDS1/NDS12
225 case 0x01: // date & time
236 case 0x67: // signature
239 case 0xE9: // tier dates
240 case 0xF8: // Old PPV Event Record
243 i += cta_res[i + 1] + 2; // skip length + 2 bytes (type and length)
246 default: // default to assume a length byte
248 rdr_log(reader, "class48 ins36: returned unknown type=0x%02X - parsing may fail", cta_res[i]);
249 i += cta_res[i + 1] + 2;
256 rdr_log_dbg(reader, D_READER, "calculated BoxID: %02X%02X%02X%02X", boxID[0], boxID[1], boxID[2], boxID[3]);
259 /* the boxid is specified in the config */
260 if(reader
->boxid
> 0)
263 for(i
= 0; i
< 4; i
++)
265 boxID
[i
] = (reader
->boxid
>> (8 * (3 - i
))) % 0x100;
267 rdr_log_dbg(reader
, D_READER
, "oscam.server BoxID: %02X%02X%02X%02X", boxID
[0], boxID
[1], boxID
[2], boxID
[3]);
272 rdr_log(reader
, "no boxID available");
277 static const unsigned char ins484C
[5] = { 0x48, 0x4C, 0x00, 0x00, 0x09 };
278 unsigned char payload4C
[9] = { 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02 };
279 memcpy(payload4C
, boxID
, 4);
280 if(!write_cmd_vg(ins484C
, payload4C
) || !status_ok(cta_res
+ cta_lr
- 2))
282 rdr_log(reader
, "class48 ins4C: sending boxid failed");
286 static const unsigned char ins4858
[5] = { 0x48, 0x58, 0x00, 0x00, 0x35 };
287 if(!write_cmd_vg(ins4858
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
289 rdr_log(reader
, "class48 ins58: failed");
293 memset(reader
->hexserial
, 0, 8);
294 memcpy(reader
->hexserial
+ 2, cta_res
+ 4, 4);
295 memcpy(reader
->sa
, cta_res
+ 4, 3);
296 reader
->caid
= cta_res
[2] * 0x100 + cta_res
[3];
298 /* we have one provider, 0x0000 */
300 memset(reader
->prid
, 0x00, sizeof(reader
->prid
));
302 static const unsigned char insBE
[5] = { 0x4B, 0xBE, 0x00, 0x00, 0x12 };
303 if(!write_cmd_vg(insBE
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
305 rdr_log(reader
, "class4B ins52: failed");
309 static const unsigned char ins4952
[5] = { 0x49, 0x52, 0x00, 0x00, 0x14 };
310 if(!write_cmd_vg(ins4952
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
312 rdr_log(reader
, "class49 ins52: failed");
316 static const unsigned char ins4958
[5] = { 0x49, 0x58, 0x00, 0x00, 0x35 };
317 if(!write_cmd_vg(ins4958
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
319 rdr_log(reader
, "class49 ins58: failed");
323 // Send BoxID class 49
324 static const unsigned char ins494C
[5] = { 0x49, 0x4C, 0x00, 0x00, 0x09 };
325 if(!write_cmd_vg(ins494C
, payload4C
) || !status_ok(cta_res
+ cta_lr
- 2))
327 rdr_log(reader
, "class49 ins4C: sending boxid failed");
331 static const unsigned char ins0C
[5] = { 0x49, 0x0C, 0x00, 0x00, 0x0A };
332 if(!write_cmd_vg(ins0C
, NULL
) || !status_ok(cta_res
+ cta_lr
- 2))
334 rdr_log(reader
, "class49 ins0C: failed");
338 rdr_log_sensitive(reader
,
339 "type: VideoGuard, caid: %04X, serial: {%02X%02X%02X%02X}, BoxID: {%02X%02X%02X%02X}",
340 reader
->caid
, reader
->hexserial
[2], reader
->hexserial
[3], reader
->hexserial
[4], reader
->hexserial
[5], boxID
[0], boxID
[1], boxID
[2], boxID
[3]);
341 rdr_log(reader
, "ready for requests - this is in testing please send -d 255 logs to rebdog");
346 static int32_t videoguard12_do_ecm(struct s_reader
*reader
, const ECM_REQUEST
*er
, struct s_ecm_answer
*ea
)
348 unsigned char cta_res
[CTA_RES_LEN
];
349 unsigned char ins40
[5] = { 0x49, 0x40, 0x40, 0x80, 0xFF };
350 static const unsigned char ins54
[5] = { 0x4B, 0x54, 0x00, 0x00, 0x17 };
351 int32_t posECMpart2
= er
->ecm
[6] + 7;
352 int32_t lenECMpart2
= er
->ecm
[posECMpart2
];
353 unsigned char tbuff
[264];
354 unsigned char rbuff
[264];
355 memcpy(&tbuff
[0], &(er
->ecm
[posECMpart2
+ 1]), lenECMpart2
);
356 ins40
[4] = lenECMpart2
;
358 l
= vg12_do_cmd(reader
, ins40
, tbuff
, NULL
, cta_res
);
359 if(l
> 0 && status_ok(cta_res
))
361 l
= vg12_do_cmd(reader
, ins54
, NULL
, rbuff
, cta_res
);
362 if(l
> 0 && status_ok(cta_res
+ l
))
364 if(!cw_is_valid(rbuff
+ 5)) //sky cards report 90 00 = ok but send cw = 00 when channel not subscribed
366 rdr_log(reader
, "class4B ins54 status 90 00 but cw=00 -> channel not subscribed");
372 memset(ea
->cw
+ 0, 0, 8);
373 memcpy(ea
->cw
+ 8, rbuff
+ 5, 8);
377 memcpy(ea
->cw
+ 0, rbuff
+ 5, 8);
378 memset(ea
->cw
+ 8, 0, 8);
383 rdr_log(reader
, "class4B ins54 (%d) status not ok %02x %02x", l
, cta_res
[0], cta_res
[1]);
387 static int32_t videoguard12_do_emm(struct s_reader
*reader
, EMM_PACKET
*ep
)
389 return videoguard_do_emm(reader
, ep
, 0x49, read_tiers
, vg12_do_cmd
);
392 static int32_t videoguard12_card_info(struct s_reader
*reader
)
394 /* info is displayed in init, or when processing info */
395 struct videoguard_data
*csystem_data
= reader
->csystem_data
;
396 rdr_log(reader
, "card detected");
397 rdr_log(reader
, "type: %s", csystem_data
->card_desc
);
402 const struct s_cardsystem reader_videoguard12
=
404 .desc
= "videoguard12",
405 .caids
= (uint16_t[]){ 0x09, 0 },
406 .do_emm
= videoguard12_do_emm
,
407 .do_ecm
= videoguard12_do_ecm
,
408 .card_info
= videoguard12_card_info
,
409 .card_init
= videoguard12_card_init
,
410 .get_emm_type
= videoguard_get_emm_type
,
411 .get_emm_filter
= videoguard_get_emm_filter
,