source: branches/monitor-improvement/reader-common.c@ 1269

Last change on this file since 1269 was 1257, checked in by alno, 13 years ago

WebIf:

  • Merged Rev 1252-1253 of trunk
File size: 12.8 KB
Line 
1#include "globals.h"
2#include "reader-common.h"
3
4int oscam_card_detect;
5
6uchar cta_cmd[272], cta_res[CTA_RES_LEN], atr[64];
7ushort cta_lr, atr_size=0;
8static int cs_ptyp_orig; //reinit=1,
9
10#define SC_IRDETO 1
11#define SC_CRYPTOWORKS 2
12#define SC_VIACCESS 3
13#define SC_CONAX 4
14#define SC_SECA 5
15#define SC_VIDEOGUARD2 6
16#define SC_DRE 7
17#define SC_NAGRA 8
18
19#ifdef TUXBOX
20static int reader_device_type(char *device)
21{
22 int rc=reader[ridx].typ;
23 struct stat sb;
24 if (reader[ridx].typ == R_MOUSE)
25 {
26 if (!stat(device, &sb))
27 {
28 if (S_ISCHR(sb.st_mode))
29 {
30 int dev_major, dev_minor;
31 dev_major=major(sb.st_rdev);
32 dev_minor=minor(sb.st_rdev);
33 if ((cs_hw==CS_HW_DBOX2) && ((dev_major==4) || (dev_major==5)))
34 switch(dev_minor & 0x3F)
35 {
36 case 0: rc=R_DB2COM1; break;
37 case 1: rc=R_DB2COM2; break;
38 }
39 cs_debug("device is major: %d, minor: %d, typ=%d", dev_major, dev_minor, rc);
40 }
41 }
42 }
43 reader[ridx].typ = rc;
44 return(rc);
45}
46#endif
47
48static void reader_nullcard(void)
49{
50 reader[ridx].card_system=0;
51 memset(reader[ridx].hexserial, 0 , sizeof(reader[ridx].hexserial));
52 memset(reader[ridx].prid , 0xFF, sizeof(reader[ridx].prid ));
53 memset(reader[ridx].caid , 0 , sizeof(reader[ridx].caid ));
54 memset(reader[ridx].availkeys, 0 , sizeof(reader[ridx].availkeys));
55 reader[ridx].acs=0;
56 reader[ridx].nprov=0;
57}
58
59int reader_doapi(uchar dad, uchar *buf, int l, int dbg)
60{
61#ifdef HAVE_PCSC
62 if (reader[ridx].typ == R_PCSC) {
63 return (dad == 0) ? pcsc_reader_do_api(&reader[ridx], buf, cta_res, &cta_lr,l) : 0;
64 }
65
66#endif
67 int rc;
68 uchar sad;
69
70// oscam_card_inserted=4;
71 sad=2;
72 cta_lr=sizeof(cta_res)-1;
73 cs_ptyp_orig=cs_ptyp;
74 cs_ptyp=dbg;
75 //cs_ddump(buf, l, "send %d bytes to ctapi", l);
76 rc=CT_data(1, &dad, &sad, l, buf, &cta_lr, cta_res);
77 //cs_ddump(cta_res, cta_lr, "received %d bytes from ctapi with rc=%d", cta_lr, rc);
78 cs_ptyp=cs_ptyp_orig;
79 return(rc);
80}
81
82int reader_chkicc(uchar *buf, int l)
83{
84 return(reader_doapi(1, buf, l, D_WATCHDOG));
85}
86
87int reader_cmd2api(uchar *buf, int l)
88{
89 return(reader_doapi(1, buf, l, D_DEVICE));
90}
91
92int reader_cmd2icc(uchar *buf, int l)
93{
94 int rc;
95 cs_ddump(buf, l, "write to cardreader %s:",reader[ridx].label);
96 rc = reader_doapi(0, buf, l, D_DEVICE);
97 cs_ddump(cta_res, cta_lr, "answer from cardreader %s:", reader[ridx].label);
98 return rc;
99}
100
101#define CMD_LEN 5
102
103int card_write(uchar *cmd, uchar *data)
104{
105 if (data) {
106 uchar buf[256]; //only allocate buffer when its needed
107 memcpy(buf, cmd, CMD_LEN);
108 if (cmd[4]) memcpy(buf+CMD_LEN, data, cmd[4]);
109 return(reader_cmd2icc(buf, CMD_LEN+cmd[4]));
110 }
111 else
112 return(reader_cmd2icc(cmd, CMD_LEN));
113}
114
115static int reader_activate_card()
116{
117 int i;
118 char ret;
119
120#ifdef HAVE_PCSC
121 if (reader[ridx].typ == R_PCSC) {
122 return (pcsc_activate_card(&reader[ridx], atr, &atr_size));
123 }
124#endif
125
126 cta_cmd[0] = CTBCS_INS_RESET;
127 cta_cmd[1] = CTBCS_P2_RESET_GET_ATR;
128 cta_cmd[2] = 0x00;
129
130 ret = reader_cmd2api(cta_cmd, 3);
131 if (ret!=OK)
132 {
133 cs_log("Error reset terminal: %d", ret);
134 return(0);
135 }
136
137 cta_cmd[0] = CTBCS_CLA;
138 cta_cmd[1] = CTBCS_INS_STATUS;
139 cta_cmd[2] = CTBCS_P1_CT_KERNEL;
140 cta_cmd[3] = CTBCS_P2_STATUS_ICC;
141 cta_cmd[4] = 0x00;
142
143// ret=reader_cmd2api(cmd, 11); warum 11 ??????
144 ret=reader_cmd2api(cta_cmd, 5);
145 if (ret!=OK)
146 {
147 cs_log("Error getting status of terminal: %d", ret);
148 return(0);
149 }
150 if (cta_res[0]!=CTBCS_DATA_STATUS_CARD_CONNECT)
151 return(0);
152
153 /* Activate card */
154// for (i=0; (i<5) && ((ret!=OK)||(cta_res[cta_lr-2]!=0x90)); i++)
155 for (i=0; i<5; i++)
156 {
157 //reader_irdeto_mode = i%2 == 1; //does not work when overclocking
158 cta_cmd[0] = CTBCS_CLA;
159 cta_cmd[1] = CTBCS_INS_REQUEST;
160 cta_cmd[2] = CTBCS_P1_INTERFACE1;
161 cta_cmd[3] = CTBCS_P2_REQUEST_GET_ATR;
162 cta_cmd[4] = 0x00;
163
164 ret=reader_cmd2api(cta_cmd, 5);
165 if ((ret==OK)||(cta_res[cta_lr-2]==0x90))
166 {
167 i=100;
168 break;
169 }
170 cs_log("Error activating card: %d", ret);
171 cs_sleepms(500);
172 }
173 if (i<100) return(0);
174
175 /* Store ATR */
176 atr_size=cta_lr-2;
177 memcpy(atr, cta_res, atr_size);
178#ifdef CS_RDR_INIT_HIST
179 reader[ridx].init_history_pos=0;
180 memset(reader[ridx].init_history, 0, sizeof(reader[ridx].init_history));
181#endif
182 cs_ri_log("ATR: %s", cs_hexdump(1, atr, atr_size));
183 sleep(1);
184 return(1);
185}
186
187void do_emm_from_file(void)
188{
189 //now here check whether we have EMM's on file to load and write to card:
190 if (reader[ridx].emmfile[0]) {//readnano has something filled in
191
192 //handling emmfile
193 char token[256];
194 FILE *fp;
195 size_t result;
196 if ((reader[ridx].emmfile[0] == '/'))
197 sprintf (token, "%s", reader[ridx].emmfile); //pathname included
198 else
199 sprintf (token, "%s%s", cs_confdir, reader[ridx].emmfile); //only file specified, look in confdir for this file
200
201 if (!(fp = fopen (token, "rb")))
202 cs_log ("ERROR: Cannot open EMM file '%s' (errno=%d)\n", token, errno);
203 else {
204 EMM_PACKET *eptmp;
205 eptmp = malloc (sizeof(EMM_PACKET));
206 result = fread (eptmp, sizeof(EMM_PACKET), 1, fp);
207 fclose (fp);
208
209 uchar old_b_nano = reader[ridx].b_nano[eptmp->emm[0]]; //save old b_nano value
210 reader[ridx].b_nano[eptmp->emm[0]] &= 0xfc; //clear lsb and lsb+1, so no blocking, and no saving for this nano
211
212 //if (!reader_do_emm (eptmp))
213 if (!reader_emm (eptmp))
214 cs_log ("ERROR: EMM read from file %s NOT processed correctly!", token);
215
216 reader[ridx].b_nano[eptmp->emm[0]] = old_b_nano; //restore old block/save settings
217 reader[ridx].emmfile[0] = 0; //clear emmfile, so no reading anymore
218
219 free(eptmp);
220 eptmp = NULL;
221 }
222 }
223}
224
225void reader_card_info()
226{
227// int rc=-1;
228 if (reader_checkhealth())
229 //if (rc=reader_checkhealth())
230 {
231 client[cs_idx].last=time((time_t)0);
232 cs_ri_brk(0);
233 do_emm_from_file();
234 switch(reader[ridx].card_system)
235 {
236 case SC_NAGRA:
237 nagra2_card_info(); break;
238 case SC_IRDETO:
239 irdeto_card_info(); break;
240 case SC_CRYPTOWORKS:
241 cryptoworks_card_info(); break;
242 case SC_VIACCESS:
243 viaccess_card_info(); break;
244 case SC_CONAX:
245 conax_card_info(); break;
246 case SC_VIDEOGUARD2:
247 videoguard_card_info(); break;
248 case SC_SECA:
249 seca_card_info(); break;
250 case SC_DRE:
251 dre_card_info(); break;
252 }
253 reader[ridx].online = 1; //do not check on rc, because error in cardinfo should not be fatal
254 }
255}
256
257static int reader_get_cardsystem(void)
258{
259 if (nagra2_card_init(atr)) reader[ridx].card_system=SC_NAGRA; else
260 if (irdeto_card_init(atr)) reader[ridx].card_system=SC_IRDETO; else
261 if (conax_card_init(atr)) reader[ridx].card_system=SC_CONAX; else
262 if (cryptoworks_card_init(atr)) reader[ridx].card_system=SC_CRYPTOWORKS; else
263 if (seca_card_init(atr)) reader[ridx].card_system=SC_SECA; else
264 if (viaccess_card_init(atr)) reader[ridx].card_system=SC_VIACCESS; else
265 if (videoguard_card_init(atr, atr_size)) reader[ridx].card_system=SC_VIDEOGUARD2; else
266 if (dre_card_init(atr)) reader[ridx].card_system=SC_DRE; else
267 cs_ri_log("card system not supported");
268 cs_ri_brk(1);
269
270 return(reader[ridx].card_system);
271}
272
273static int reader_reset(void)
274{
275 reader_nullcard();
276 if (!reader_activate_card()) return(0);
277 return(reader_get_cardsystem());
278}
279
280static int reader_card_inserted(void)
281{
282#ifdef HAVE_PCSC
283 if (reader[ridx].typ == R_PCSC) {
284 return(pcsc_check_card_inserted(&reader[ridx]));
285
286 }
287#endif
288
289 cta_cmd[0]=CTBCS_CLA;
290 cta_cmd[1]=CTBCS_INS_STATUS;
291 cta_cmd[2]=CTBCS_P1_INTERFACE1;
292 cta_cmd[3]=CTBCS_P2_STATUS_ICC;
293 cta_cmd[4]=0x00;
294
295 return(reader_chkicc(cta_cmd, 5) ? 0 : cta_res[0]);
296}
297
298int reader_device_init(char *device)
299{
300#ifdef HAVE_PCSC
301 if (reader[ridx].typ == R_PCSC) {
302 return (pcsc_reader_init(&reader[ridx], device));
303 }
304#endif
305
306 int rc;
307 oscam_card_detect=reader[ridx].detect;
308 cs_ptyp_orig=cs_ptyp;
309 cs_ptyp=D_DEVICE;
310#ifdef TUXBOX
311 reader[ridx].typ = reader_device_type(device);
312 if ((rc=CT_init(1))!=OK)
313 cs_log("[tuxbox] Cannot open device: %s", device);
314#else
315 if ((rc=CT_init(1))!=OK)
316 cs_log("Cannot open device: %s", device);
317#endif
318 cs_debug("ct_init on %s: %d", device, rc);
319 cs_ptyp=cs_ptyp_orig;
320 return((rc!=OK) ? 2 : 0);
321}
322
323int reader_checkhealth(void)
324{
325 if (reader_card_inserted())
326 {
327 if (!(reader[ridx].card_status & CARD_INSERTED))
328 {
329 cs_log("card detected");
330 reader[ridx].card_status = CARD_NEED_INIT;
331 reader[ridx].card_status = CARD_INSERTED | (reader_reset() ? 0 : CARD_FAILURE);
332 if (reader[ridx].card_status & CARD_FAILURE)
333 {
334 cs_log("card initializing error");
335 }
336 else
337 {
338 client[cs_idx].au=ridx;
339 reader_card_info();
340 }
341
342 int i;
343 for( i=1; i<CS_MAXPID; i++ ) {
344 if( client[i].pid && client[i].typ=='c' && client[i].usr[0] ) {
345 kill(client[i].pid, SIGQUIT);
346 }
347 }
348 }
349 }
350 else
351 {
352 if (reader[ridx].card_status & CARD_INSERTED)
353 {
354 reader_nullcard();
355 client[cs_idx].lastemm=0;
356 client[cs_idx].lastecm=0;
357 client[cs_idx].au=-1;
358 extern int io_serial_need_dummy_char;
359 io_serial_need_dummy_char=0;
360 cs_log("card ejected");
361 }
362 reader[ridx].card_status=0;
363 reader[ridx].online=0;
364 }
365 return reader[ridx].card_status==CARD_INSERTED;
366}
367
368void reader_post_process(void)
369{
370 // some systems eg. nagra2/3 needs post process after receiving cw from card
371 // To save ECM/CW time we added this function after writing ecm answer
372 switch(reader[ridx].card_system)
373 {
374 case SC_NAGRA:
375 nagra2_post_process(); break;
376 default: break;
377 }
378}
379
380int reader_ecm(ECM_REQUEST *er)
381{
382 int rc=-1;
383 if( (rc=reader_checkhealth()) )
384 {
385 if( (reader[ridx].caid[0]>>8)==((er->caid>>8)&0xFF) )
386 {
387 client[cs_idx].last_srvid=er->srvid;
388 client[cs_idx].last_caid=er->caid;
389 client[cs_idx].last=time((time_t)0);
390 switch(reader[ridx].card_system)
391 {
392 case SC_NAGRA:
393 rc=(nagra2_do_ecm(er)) ? 1 : 0; break;
394 case SC_IRDETO:
395 rc=(irdeto_do_ecm(er)) ? 1 : 0; break;
396 case SC_CRYPTOWORKS:
397 rc=(cryptoworks_do_ecm(er)) ? 1 : 0; break;
398 case SC_VIACCESS:
399 rc=(viaccess_do_ecm(er)) ? 1 : 0; break;
400 case SC_CONAX:
401 rc=(conax_do_ecm(er)) ? 1 : 0; break;
402 case SC_SECA:
403 rc=(seca_do_ecm(er)) ? 1 : 0; break;
404 case SC_VIDEOGUARD2:
405 rc=(videoguard_do_ecm(er)) ? 1 : 0; break;
406 case SC_DRE:
407 rc=(dre_do_ecm(er)) ? 1: 0; break;
408 default: rc=0;
409 }
410 }
411 else
412 rc=0;
413 }
414 return(rc);
415}
416
417int reader_emm(EMM_PACKET *ep)
418{
419 int rc=-1;
420
421 rc=reader_checkhealth();
422 if (rc)
423 {
424 client[cs_idx].last=time((time_t)0);
425 if (reader[ridx].b_nano[ep->emm[0]] & 0x02) //should this nano be saved?
426 {
427 char token[256];
428 FILE *fp;
429
430 time_t rawtime;
431 time (&rawtime);
432 struct tm *timeinfo;
433 timeinfo = localtime (&rawtime); /* to access LOCAL date/time info */
434 char buf[80];
435 strftime (buf, 80, "%Y%m%d_%H_%M_%S", timeinfo);
436
437 sprintf (token, "%swrite_%s_%s.%s", cs_confdir, (ep->emm[0] == 0x82) ? "UNIQ" : "SHARED", buf, "txt");
438 if (!(fp = fopen (token, "w")))
439 {
440 cs_log ("ERROR: Cannot open EMM.txt file '%s' (errno=%d)\n", token, errno);
441 }
442 else
443 {
444 cs_log ("Succesfully written text EMM to %s.", token);
445 int emm_length = ((ep->emm[1] & 0x0f) << 8) | ep->emm[2];
446 fprintf (fp, "%s", cs_hexdump (0, ep->emm, emm_length + 3));
447 fclose (fp);
448 }
449
450 //sprintf (token, "%s%s.%s", cs_confdir, buf,"emm");
451 sprintf (token, "%swrite_%s_%s.%s", cs_confdir, (ep->emm[0] == 0x82) ? "UNIQ" : "SHARED", buf, "emm");
452 if (!(fp = fopen (token, "wb")))
453 {
454 cs_log ("ERROR: Cannot open EMM.emm file '%s' (errno=%d)\n", token, errno);
455 }
456 else
457 {
458 if (fwrite(ep, sizeof (*ep), 1, fp) == 1)
459 {
460 cs_log ("Succesfully written binary EMM to %s.", token);
461 }
462 else
463 {
464 cs_log ("ERROR: Cannot write binary EMM to %s (errno=%d)\n", token, errno);
465 }
466 fclose (fp);
467 }
468 }
469
470 if (reader[ridx].b_nano[ep->emm[0]] & 0x01) //should this nano be blcoked?
471 return 3;
472
473 switch(reader[ridx].card_system)
474 {
475 case SC_NAGRA:
476 rc=nagra2_do_emm(ep); break;
477 case SC_IRDETO:
478 rc=irdeto_do_emm(ep); break;
479 case SC_CRYPTOWORKS:
480 rc=cryptoworks_do_emm(ep); break;
481 case SC_VIACCESS:
482 rc=viaccess_do_emm(ep); break;
483 case SC_CONAX:
484 rc=conax_do_emm(ep); break;
485 case SC_SECA:
486 rc=seca_do_emm(ep); break;
487 case SC_VIDEOGUARD2:
488 rc=videoguard_do_emm(ep); break;
489 case SC_DRE:
490 rc=dre_do_emm(ep); break;
491 default: rc=0;
492 }
493 }
494 return(rc);
495}
Note: See TracBrowser for help on using the repository browser.