2 #ifdef READER_VIDEOGUARD
3 #include "reader-common.h"
4 #include "reader-videoguard-common.h"
6 static int32_t vg1_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);
46 static void read_tiers(struct s_reader
*reader
)
48 struct videoguard_data
*csystem_data
= reader
->csystem_data
;
50 //const uint8_t ins2a[5] = { 0x48, 0x2a, 0x00, 0x00, 0x00 };
53 //return; // Not working at present so just do nothing
55 //l = vg1_do_cmd(reader, ins2a, NULL, NULL, cta_res);
56 //if (l < 0 || !status_ok(cta_res + l))
61 uint8_t ins76
[5] = { 0x48, 0x76, 0x00, 0x00, 0x00 };
65 if(!write_cmd_vg(ins76
, NULL
) || !status_ok(cta_res
+ 2))
72 int32_t num
= cta_res
[1];
75 cs_clear_entitlement(reader
); // reset the entitlements
77 for(i
= 0; i
< num
; i
++)
80 l
= vg1_do_cmd(reader
, ins76
, NULL
, NULL
, cta_res
);
82 if(l
< 0 || !status_ok(cta_res
+ l
))
87 if(cta_res
[2] == 0 && cta_res
[3] == 0)
92 uint16_t tier_id
= (cta_res
[2] << 8) | cta_res
[3];
93 // add entitlements to list
95 memset(&timeinfo
, 0, sizeof(struct tm
));
96 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);
99 rdr_log(reader
, "tier: %04x, expiry date: %04d/%02d/%02d-%02d:%02d:%02d %s",
100 tier_id
, timeinfo
.tm_year
+ 1900, timeinfo
.tm_mon
+ 1, timeinfo
.tm_mday
, timeinfo
.tm_hour
,
101 timeinfo
.tm_min
, timeinfo
.tm_sec
, get_tiername(tier_id
, reader
->caid
, tiername
));
105 static int32_t videoguard1_card_init(struct s_reader
*reader
, ATR
*newatr
)
108 /* 40 B0 09 4A 50 01 4E 5A */
109 if((hist_size
< 7) || (hist
[1] != 0xB0) || (hist
[3] != 0x4A) || (hist
[4] != 0x50))
117 if(!cs_malloc(&reader
->csystem_data
, sizeof(struct videoguard_data
)))
121 struct videoguard_data
*csystem_data
= reader
->csystem_data
;
123 /* set information on the card stored in reader-videoguard-common.c */
124 set_known_card_info(reader
, atr
, &atr_size
);
126 if((reader
->ndsversion
!= NDS1
) && ((csystem_data
->card_system_version
!= NDS1
) || (reader
->ndsversion
!= NDSAUTO
)))
128 /* known ATR and not NDS1
129 or unknown ATR and not forced to NDS1
130 or known NDS1 ATR and forced to another NDS version
131 ...probably not NDS1 */
135 rdr_log(reader
, "type: %s, baseyear: %i", csystem_data
->card_desc
, csystem_data
->card_baseyear
);
136 if(reader
->ndsversion
== NDS1
)
138 rdr_log(reader
, "forced to NDS1+");
141 /* NDS1 Class 48 only cards only need a very basic initialisation
142 NDS1 Class 48 only cards do not respond to vg1_do_cmd(ins7416)
143 nor do they return list of valid command therefore do not even try
144 NDS1 Class 48 only cards need to be told the length as (48, ins, 00, 80, 01)
145 does not return the length */
149 memset(buff
, 0, sizeof(buff
));
151 /* Try to get the boxid from the card, even if BoxID specified in the config file
152 also used to check if it is an NDS1 card as the returned information will
153 not be encrypted if it is an NDS1 card */
155 static const uint8_t ins36
[5] = { 0x48, 0x36, 0x00, 0x00, 0x90 };
158 l
= vg1_do_cmd(reader
, ins36
, NULL
, buff
, cta_res
);
162 rdr_log(reader
, "class48 ins36: encrypted - therefore not an NDS1 card");
167 /* skipping the initial fixed fields: cmdecho (4) + length (1) + encr/rev++ (4) */
172 if(!gotUA
&& buff
[i
] < 0xF0) /* then we guess that the next 4 bytes is the UA */
179 switch(buff
[i
]) /* object length vary depending on type */
181 case 0x00: /* padding */
187 case 0xEF: /* card status */
199 case 0xDF: /* next server contact */
205 case 0xF3: /* boxID */
207 memcpy(&boxID
, &buff
[i
+ 1], sizeof(boxID
));
219 case 0xFC: /* No idea seems to with with NDS1 */
225 case 0x01: /* date & time */
238 case 0x67: /* signature */
241 case 0xE9: /* tier dates */
242 case 0xF8: /* Old PPV Event Record */
245 i
+= buff
[i
+ 1] + 2; /* skip length + 2 bytes (type and length) */
249 default: /* default to assume a length byte */
251 rdr_log(reader
, "class48 ins36: returned unknown type=0x%02X - parsing may fail", buff
[i
]);
252 i
+= buff
[i
+ 1] + 2;
259 // rdr_log(reader, "calculated BoxID: %02X%02X%02X%02X", boxID[0], boxID[1], boxID[2], boxID[3]);
261 /* the boxid is specified in the config */
262 if(reader
->boxid
> 0)
265 for(i
= 0; i
< 4; i
++)
267 boxID
[i
] = (reader
->boxid
>> (8 * (3 - i
))) % 0x100;
269 // rdr_log(reader, "config BoxID: %02X%02X%02X%02X", boxID[0], boxID[1], boxID[2], boxID[3]);
274 rdr_log(reader
, "no boxID available");
279 static const uint8_t ins4C
[5] = { 0x48, 0x4C, 0x00, 0x00, 0x09 };
280 uint8_t payload4C
[9] = { 0, 0, 0, 0, 3, 0, 0, 0, 4 };
281 memcpy(payload4C
, boxID
, 4);
283 if(!write_cmd_vg(ins4C
, payload4C
) || !status_ok(cta_res
+ l
))
285 rdr_log(reader
, "class48 ins4C: sending boxid failed");
289 static const uint8_t ins58
[5] = { 0x48, 0x58, 0x00, 0x00, 0x17 };
290 l
= vg1_do_cmd(reader
, ins58
, NULL
, buff
, cta_res
);
293 rdr_log(reader
, "class48 ins58: failed");
297 memset(reader
->hexserial
, 0, 8);
298 memcpy(reader
->hexserial
+ 2, cta_res
+ 1, 4);
299 memcpy(reader
->sa
, cta_res
+ 1, 3);
300 //reader->caid = cta_res[24] * 0x100 + cta_res[25];
301 /* Force caid until can figure out how to get it */
302 reader
->caid
= 0x9 * 0x100 + 0x69;
304 /* we have one provider, 0x0000 */
306 memset(reader
->prid
, 0x00, sizeof(reader
->prid
));
308 rdr_log_sensitive(reader
, "type: VideoGuard, caid: %04X, serial: {%02X%02X%02X%02X}, BoxID: {%02X%02X%02X%02X}",
309 reader
->caid
, reader
->hexserial
[2], reader
->hexserial
[3], reader
->hexserial
[4], reader
->hexserial
[5],
310 boxID
[0], boxID
[1], boxID
[2], boxID
[3]);
311 rdr_log(reader
, "ready for requests - this is in testing please send -d 255 logs");
316 static int32_t videoguard1_do_ecm(struct s_reader
*reader
, const ECM_REQUEST
*er
, struct s_ecm_answer
*ea
)
318 uint8_t cta_res
[CTA_RES_LEN
];
319 uint8_t ins40
[5] = { 0x48, 0x40, 0x00, 0x80, 0xFF };
320 static const uint8_t ins54
[5] = { 0x48, 0x54, 0x00, 0x00, 0x0D };
321 int32_t posECMpart2
= er
->ecm
[6] + 7;
322 int32_t lenECMpart2
= er
->ecm
[posECMpart2
];
325 memcpy(&tbuff
[0], &(er
->ecm
[posECMpart2
+ 1]), lenECMpart2
);
326 ins40
[4] = lenECMpart2
;
328 l
= vg1_do_cmd(reader
, ins40
, tbuff
, NULL
, cta_res
);
330 if(l
> 0 && status_ok(cta_res
))
332 l
= vg1_do_cmd(reader
, ins54
, NULL
, rbuff
, cta_res
);
333 if(l
> 0 && status_ok(cta_res
+ l
))
335 if(!cw_is_valid(rbuff
+ 5)) // sky cards report 90 00 = ok but send cw = 00 when channel not subscribed
337 rdr_log(reader
, "class48 ins54 status 90 00 but cw=00 -> channel not subscribed");
343 memset(ea
->cw
+ 0, 0, 8);
344 memcpy(ea
->cw
+ 8, rbuff
+ 5, 8);
348 memcpy(ea
->cw
+ 0, rbuff
+ 5, 8);
349 memset(ea
->cw
+ 8, 0, 8);
354 rdr_log(reader
, "class48 ins54 (%d) status not ok %02x %02x", l
, cta_res
[0], cta_res
[1]);
358 static int32_t videoguard1_do_emm(struct s_reader
*reader
, EMM_PACKET
*ep
)
360 return videoguard_do_emm(reader
, ep
, 0x48, read_tiers
, vg1_do_cmd
);
363 static int32_t videoguard1_card_info(struct s_reader
*reader
)
365 /* info is displayed in init, or when processing info */
366 struct videoguard_data
*csystem_data
= reader
->csystem_data
;
367 rdr_log(reader
, "card detected");
368 rdr_log(reader
, "type: %s", csystem_data
->card_desc
);
373 const struct s_cardsystem reader_videoguard1
=
375 .desc
= "videoguard1",
376 .caids
= (uint16_t[]){ 0x09, 0 },
377 .do_emm
= videoguard1_do_emm
,
378 .do_ecm
= videoguard1_do_ecm
,
379 .card_info
= videoguard1_card_info
,
380 .card_init
= videoguard1_card_init
,
381 .get_emm_type
= videoguard_get_emm_type
,
382 .get_emm_filter
= videoguard_get_emm_filter
,