revert breaks some stupid old compilers
[oscam.git] / reader-videoguard12.c
blobbde2889a0527128ffd1c4b0cbfba0a03716779b5
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 unsigned char *ins, const unsigned char *txbuff, unsigned char *rxbuff, unsigned char *cta_res)
8 uint16_t cta_lr;
9 unsigned char ins2[5];
10 memcpy(ins2, ins, 5);
11 unsigned char len = 0;
12 len = ins2[4];
15 if(txbuff == NULL)
17 if(!write_cmd_vg(ins2, NULL) || !status_ok(cta_res + len))
19 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, (uchar *) txbuff) || !status_ok(cta_res))
32 return -2;
34 if(rxbuff != NULL)
36 memcpy(rxbuff, ins2, 5);
37 memcpy(rxbuff + 5, txbuff, len);
38 memcpy(rxbuff + 5 + len, cta_res, 2);
41 return len;
44 static void read_tiers(struct s_reader *reader)
46 def_resp;
48 static const unsigned char ins2A[5] = { 0x48, 0x2A, 0x00, 0x00, 0x90 };
49 int32_t l;
51 if(!write_cmd_vg(ins2A, NULL) || !status_ok(cta_res + cta_lr - 2))
53 rdr_log(reader, "class48 ins2A: failed");
54 return;
57 // return at present as not sure how to parse this
58 return;
60 unsigned char ins76[5] = { 0x48, 0x76, 0x00, 0x00, 0x00 };
61 ins76[3] = 0x7f;
62 ins76[4] = 2;
63 if(!write_cmd_vg(ins76, NULL) || !status_ok(cta_res + 2))
65 return;
67 ins76[3] = 0;
68 ins76[4] = 0x0a;
69 int32_t num = cta_res[1];
70 int32_t i;
72 cs_clear_entitlement(reader); //reset the entitlements
74 struct videoguard_data *csystem_data = reader->csystem_data;
75 for(i = 0; i < num; i++)
77 ins76[2] = i;
78 l = vg12_do_cmd(reader, ins76, NULL, NULL, cta_res);
79 if(l < 0 || !status_ok(cta_res + l))
81 return;
83 if(cta_res[2] == 0 && cta_res[3] == 0)
85 break;
87 uint16_t tier_id = (cta_res[2] << 8) | cta_res[3];
88 struct tm timeinfo;
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);
92 char tiername[83];
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)
100 get_hist;
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");
105 return ERROR;
107 rdr_log_dbg(reader, D_READER, "passed history check");
109 get_atr;
110 def_resp;
112 if(!cs_malloc(&reader->csystem_data, sizeof(struct videoguard_data)))
113 { return ERROR; }
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 */
125 return ERROR;
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");
144 //return ERROR;
146 if(!write_cmd_vg(ins4852, NULL) || !status_ok(cta_res + cta_lr - 2))
148 rdr_log(reader, "class48 ins52: failed");
149 //return ERROR;
152 unsigned char boxID[4];
153 int32_t boxidOK = 0;
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");
163 //return ERROR;
164 } else {
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");
172 //return ERROR;
175 if (cta_res[2] > 0x0F) {
176 rdr_log(reader, "class48 ins36: encrypted - therefore not an NDS12 card");
177 // return ERROR;
178 } else {
179 // skipping the initial fixed fields: encr/rev++ (4)
180 int32_t i = 4;
181 int32_t gotUA = 0;
182 while (i < (cta_lr-2)) {
183 if (!gotUA && cta_res[i] < 0xF0) { // then we guess that the next 4 bytes is the UA
184 gotUA = 1;
185 i += 4;
186 } else {
187 switch (cta_res[i]) { // object length vary depending on type
188 case 0x00: // padding
190 i += 1;
191 break;
193 case 0xEF: // card status
195 i += 3;
196 break;
198 case 0xD1:
200 i += 4;
201 break;
203 case 0xDF: // next server contact
205 i += 5;
206 break;
208 case 0xF3: // boxID
210 memcpy(&boxID, &cta_res[i + 1], sizeof(boxID));
211 boxidOK = 1;
212 i += 5;
213 break;
215 case 0xF6:
217 i += 6;
218 break;
220 case 0xFC: // No idea NDS1/NDS12
222 i += 14;
223 break;
225 case 0x01: // date & time
227 i += 7;
228 break;
230 case 0xFA:
232 i += 9;
233 break;
235 case 0x5E:
236 case 0x67: // signature
237 case 0xDE:
238 case 0xE2:
239 case 0xE9: // tier dates
240 case 0xF8: // Old PPV Event Record
241 case 0xFD:
243 i += cta_res[i + 1] + 2; // skip length + 2 bytes (type and length)
244 break;
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;
251 } //switch
252 }//else
253 }//while
254 }//ele
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)
262 int32_t i;
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]);
270 if(!boxidOK)
272 rdr_log(reader, "no boxID available");
273 return ERROR;
276 // Send BoxID
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");
283 //return ERROR;
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");
290 return ERROR;
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 */
299 reader->nprov = 1;
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");
306 //return ERROR;
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");
313 //return ERROR;
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");
320 //return ERROR;
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");
328 //return ERROR;
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");
335 //return ERROR;
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");
343 return OK;
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;
357 int32_t l;
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");
367 return ERROR;
370 if(er->ecm[0] & 1)
372 memset(ea->cw + 0, 0, 8);
373 memcpy(ea->cw + 8, rbuff + 5, 8);
375 else
377 memcpy(ea->cw + 0, rbuff + 5, 8);
378 memset(ea->cw + 8, 0, 8);
380 return OK;
383 rdr_log(reader, "class4B ins54 (%d) status not ok %02x %02x", l, cta_res[0], cta_res[1]);
384 return ERROR;
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);
398 read_tiers(reader);
399 return OK;
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,
414 #endif