- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / reader-videoguard12.c
blob19d5bab4f6373e6eeb8d96a0e6162802079b1109
1 #include "globals.h"
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)
8 uint16_t cta_lr;
9 uint8_t ins2[5];
10 memcpy(ins2, ins, 5);
11 uint8_t len = 0;
12 len = ins2[4];
14 if(txbuff == NULL)
16 if(!write_cmd_vg(ins2, NULL) || !status_ok(cta_res + len))
18 return -1;
21 if(rxbuff != NULL)
23 memcpy(rxbuff, ins2, 5);
24 memcpy(rxbuff + 5, cta_res, len);
25 memcpy(rxbuff + 5 + len, cta_res + len, 2);
28 else
30 if(!write_cmd_vg(ins2, (uint8_t *)txbuff) || !status_ok(cta_res))
32 return -2;
35 if(rxbuff != NULL)
37 memcpy(rxbuff, ins2, 5);
38 memcpy(rxbuff + 5, txbuff, len);
39 memcpy(rxbuff + 5 + len, cta_res, 2);
42 return len;
45 static void read_tiers(struct s_reader *reader)
47 def_resp;
49 static const uint8_t ins2A[5] = { 0x48, 0x2A, 0x00, 0x00, 0x90 };
50 int32_t l;
52 if(!write_cmd_vg(ins2A, NULL) || !status_ok(cta_res + cta_lr - 2))
54 rdr_log(reader, "class48 ins2A: failed");
55 return;
58 // return at present as not sure how to parse this
59 return;
61 uint8_t ins76[5] = { 0x48, 0x76, 0x00, 0x00, 0x00 };
62 ins76[3] = 0x7f;
63 ins76[4] = 2;
65 if(!write_cmd_vg(ins76, NULL) || !status_ok(cta_res + 2))
67 return;
70 ins76[3] = 0;
71 ins76[4] = 0x0a;
73 int32_t num = cta_res[1];
74 int32_t i;
76 cs_clear_entitlement(reader); // reset the entitlements
78 struct videoguard_data *csystem_data = reader->csystem_data;
79 for(i = 0; i < num; i++)
81 ins76[2] = i;
82 l = vg12_do_cmd(reader, ins76, NULL, NULL, cta_res);
84 if(l < 0 || !status_ok(cta_res + l))
86 return;
89 if(cta_res[2] == 0 && cta_res[3] == 0)
91 break;
94 uint16_t tier_id = (cta_res[2] << 8) | cta_res[3];
95 struct tm timeinfo;
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);
99 char tiername[83];
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)
108 get_hist;
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");
113 return ERROR;
115 rdr_log_dbg(reader, D_READER, "passed history check");
117 get_atr;
118 def_resp;
120 if(!cs_malloc(&reader->csystem_data, sizeof(struct videoguard_data)))
122 return ERROR;
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 */
135 return ERROR;
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");
154 //return ERROR;
157 if(!write_cmd_vg(ins4852, NULL) || !status_ok(cta_res + cta_lr - 2))
159 rdr_log(reader, "class48 ins52: failed");
160 //return ERROR;
163 uint8_t boxID[4];
164 int32_t boxidOK = 0;
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");
174 //return ERROR;
175 } else {
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");
183 //return ERROR;
186 if (cta_res[2] > 0x0F) {
187 rdr_log(reader, "class48 ins36: encrypted - therefore not an NDS12 card");
188 // return ERROR;
189 } else {
190 // skipping the initial fixed fields: encr/rev++ (4)
191 int32_t i = 4;
192 int32_t gotUA = 0;
193 while (i < (cta_lr-2)) {
194 if (!gotUA && cta_res[i] < 0xF0) { // then we guess that the next 4 bytes is the UA
195 gotUA = 1;
196 i += 4;
197 } else {
198 switch (cta_res[i]) { // object length vary depending on type
199 case 0x00: // padding
201 i += 1;
202 break;
204 case 0xEF: // card status
206 i += 3;
207 break;
209 case 0xD1:
211 i += 4;
212 break;
214 case 0xDF: // next server contact
216 i += 5;
217 break;
219 case 0xF3: // boxID
221 memcpy(&boxID, &cta_res[i + 1], sizeof(boxID));
222 boxidOK = 1;
223 i += 5;
224 break;
226 case 0xF6:
228 i += 6;
229 break;
231 case 0xFC: // No idea NDS1/NDS12
233 i += 14;
234 break;
236 case 0x01: // date & time
238 i += 7;
239 break;
241 case 0xFA:
243 i += 9;
244 break;
246 case 0x5E:
247 case 0x67: // signature
248 case 0xDE:
249 case 0xE2:
250 case 0xE9: // tier dates
251 case 0xF8: // Old PPV Event Record
252 case 0xFD:
254 i += cta_res[i + 1] + 2; // skip length + 2 bytes (type and length)
255 break;
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;
262 } //switch
263 }//else
264 }//while
265 }//ele
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)
273 int32_t i;
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]);
281 if(!boxidOK)
283 rdr_log(reader, "no boxID available");
284 return ERROR;
287 // Send BoxID
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");
294 //return ERROR;
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");
301 return ERROR;
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 */
310 reader->nprov = 1;
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");
317 //return ERROR;
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");
324 //return ERROR;
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");
331 //return ERROR;
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");
339 //return ERROR;
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");
346 //return ERROR;
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");
354 return OK;
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];
364 uint8_t tbuff[264];
365 uint8_t rbuff[264];
367 memcpy(&tbuff[0], &(er->ecm[posECMpart2 + 1]), lenECMpart2);
368 ins40[4] = lenECMpart2;
370 int32_t l;
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");
380 return ERROR;
383 if(er->ecm[0] & 1)
385 memset(ea->cw + 0, 0, 8);
386 memcpy(ea->cw + 8, rbuff + 5, 8);
388 else
390 memcpy(ea->cw + 0, rbuff + 5, 8);
391 memset(ea->cw + 8, 0, 8);
393 return OK;
396 rdr_log(reader, "class4B ins54 (%d) status not ok %02x %02x", l, cta_res[0], cta_res[1]);
397 return ERROR;
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);
416 read_tiers(reader);
417 return OK;
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,
433 #endif