- fix for ticker #4787
[oscam.git] / reader-videoguard1.c
blob103634221d8212b870429637e7a9929e23d43dcc
1 #include "globals.h"
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)
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);
43 return len;
46 static void read_tiers(struct s_reader *reader)
48 struct videoguard_data *csystem_data = reader->csystem_data;
49 def_resp;
50 //const uint8_t ins2a[5] = { 0x48, 0x2a, 0x00, 0x00, 0x00 };
51 int32_t l;
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))
57 //{
58 // return;
59 //}
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;
72 int32_t num = cta_res[1];
73 int32_t i;
75 cs_clear_entitlement(reader); // reset the entitlements
77 for(i = 0; i < num; i++)
79 ins76[2] = i;
80 l = vg1_do_cmd(reader, ins76, NULL, NULL, cta_res);
82 if(l < 0 || !status_ok(cta_res + l))
84 return;
87 if(cta_res[2] == 0 && cta_res[3] == 0)
89 break;
92 uint16_t tier_id = (cta_res[2] << 8) | cta_res[3];
93 // add entitlements to list
94 struct tm timeinfo;
95 memset(&timeinfo, 0, sizeof(struct tm));
96 rev_date_calc_tm(&cta_res[4], &timeinfo, csystem_data->card_baseyear);
97 char tiername[83];
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)
107 get_hist;
108 /* 40 B0 09 4A 50 01 4E 5A */
109 if((hist_size < 7) || (hist[1] != 0xB0) || (hist[3] != 0x4A) || (hist[4] != 0x50))
111 return ERROR;
114 get_atr;
115 def_resp;
117 if(!cs_malloc(&reader->csystem_data, sizeof(struct videoguard_data)))
119 return ERROR;
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 */
132 return ERROR;
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 */
147 int32_t l = 0;
148 uint8_t buff[256];
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 };
156 uint8_t boxID[4];
157 int32_t boxidOK = 0;
158 l = vg1_do_cmd(reader, ins36, NULL, buff, cta_res);
160 if(buff[7] > 0x0F)
162 rdr_log(reader, "class48 ins36: encrypted - therefore not an NDS1 card");
163 return ERROR;
165 else
167 /* skipping the initial fixed fields: cmdecho (4) + length (1) + encr/rev++ (4) */
168 int32_t i = 9;
169 int32_t gotUA = 0;
170 while(i < l)
172 if(!gotUA && buff[i] < 0xF0) /* then we guess that the next 4 bytes is the UA */
174 gotUA = 1;
175 i += 4;
177 else
179 switch(buff[i]) /* object length vary depending on type */
181 case 0x00: /* padding */
183 i += 1;
184 break;
187 case 0xEF: /* card status */
189 i += 3;
190 break;
193 case 0xD1:
195 i += 4;
196 break;
199 case 0xDF: /* next server contact */
201 i += 5;
202 break;
205 case 0xF3: /* boxID */
207 memcpy(&boxID, &buff[i + 1], sizeof(boxID));
208 boxidOK = 1;
209 i += 5;
210 break;
213 case 0xF6:
215 i += 6;
216 break;
219 case 0xFC: /* No idea seems to with with NDS1 */
221 i += 14;
222 break;
225 case 0x01: /* date & time */
227 i += 7;
228 break;
231 case 0xFA:
233 i += 9;
234 break;
237 case 0x5E:
238 case 0x67: /* signature */
239 case 0xDE:
240 case 0xE2:
241 case 0xE9: /* tier dates */
242 case 0xF8: /* Old PPV Event Record */
243 case 0xFD:
245 i += buff[i + 1] + 2; /* skip length + 2 bytes (type and length) */
246 break;
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)
264 int32_t i;
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]);
272 if(!boxidOK)
274 rdr_log(reader, "no boxID available");
275 return ERROR;
278 // Send BoxID
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");
286 return ERROR;
289 static const uint8_t ins58[5] = { 0x48, 0x58, 0x00, 0x00, 0x17 };
290 l = vg1_do_cmd(reader, ins58, NULL, buff, cta_res);
291 if(l < 0)
293 rdr_log(reader, "class48 ins58: failed");
294 return ERROR;
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 */
305 reader->nprov = 1;
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");
313 return OK;
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];
323 uint8_t tbuff[264];
324 uint8_t rbuff[264];
325 memcpy(&tbuff[0], &(er->ecm[posECMpart2 + 1]), lenECMpart2);
326 ins40[4] = lenECMpart2;
327 int32_t l;
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");
338 return ERROR;
341 if(er->ecm[0] & 1)
343 memset(ea->cw + 0, 0, 8);
344 memcpy(ea->cw + 8, rbuff + 5, 8);
346 else
348 memcpy(ea->cw + 0, rbuff + 5, 8);
349 memset(ea->cw + 8, 0, 8);
351 return OK;
354 rdr_log(reader, "class48 ins54 (%d) status not ok %02x %02x", l, cta_res[0], cta_res[1]);
355 return ERROR;
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);
369 read_tiers(reader);
370 return OK;
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,
385 #endif