source: trunk/oscam-reader.c@ 4141

Last change on this file since 4141 was 4141, checked in by dingo35, 12 years ago

all: simplify debug system, add D_DVBAPI = -d128, eliminate cs_ptyp which complicates stuff unnecc

File size: 23.7 KB
Line 
1//FIXME Not checked on threadsafety yet; after checking please remove this line
2#include "globals.h"
3
4int logfd=0;
5
6void reader_do_idle(struct s_reader * reader);
7
8void cs_ri_brk(struct s_reader * reader, int flag)
9{
10 if (flag)
11 reader->brk_pos=reader->init_history_pos;
12 else
13 reader->init_history_pos=reader->brk_pos;
14}
15
16void cs_ri_log(struct s_reader * reader, char *fmt,...)
17{
18 char txt[256];
19
20 va_list params;
21 va_start(params, fmt);
22 vsprintf(txt, fmt, params);
23 va_end(params);
24 cs_log("%s", txt);
25
26 if (cfg->saveinithistory) {
27 FILE *fp;
28 char filename[256];
29 char *buffer;
30 sprintf(filename, "%s/reader%d", get_tmp_dir(), get_ridx(reader));
31 int size = reader->init_history_pos+strlen(txt)+1;
32 buffer = malloc(size+1);
33
34 if (buffer == NULL)
35 return;
36
37 memset(buffer, 32, size);
38
39 fp = fopen(filename, "r");
40
41 if (fp) {
42 fread(buffer, 1, reader->init_history_pos, fp);
43 fclose(fp);
44 }
45
46 sprintf(buffer+reader->init_history_pos, "%s\n", txt);
47
48 fp = fopen(filename, "w");
49 if (fp) {
50 fwrite(buffer, 1, reader->init_history_pos+strlen(txt)+1, fp);
51 fclose(fp);
52 }
53
54 free(buffer);
55 }
56 reader->init_history_pos+=strlen(txt)+1;
57}
58
59static void casc_check_dcw(struct s_reader * reader, int idx, int rc, uchar *cw)
60{
61 int i;
62 struct s_client *cl = reader->client;
63 for (i=0; i<CS_MAXPENDING; i++)
64 {
65 if ((cl->ecmtask[i].rc>=10) &&
66 (!memcmp(cl->ecmtask[i].ecmd5, cl->ecmtask[idx].ecmd5, CS_ECMSTORESIZE)))
67 {
68 if (rc)
69 {
70 cl->ecmtask[i].rc=(i==idx) ? 1 : 2;
71#ifdef CS_WITH_GBOX
72 if(cl->ecmtask[i].gbxRidx)cl->ecmtask[i].rc=0;
73#endif
74 memcpy(cl->ecmtask[i].cw, cw, 16);
75 }
76 else
77 cl->ecmtask[i].rc=0;
78 write_ecm_answer(reader, &cl->ecmtask[i]);
79 cl->ecmtask[i].idx=0;
80 }
81 }
82}
83
84int casc_recv_timer(struct s_reader * reader, uchar *buf, int l, int msec)
85{
86 struct timeval tv;
87 fd_set fds;
88 int rc;
89 struct s_client *cl = reader->client;
90
91 if (!cl->pfd) return(-1);
92 tv.tv_sec = msec/1000;
93 tv.tv_usec = (msec%1000)*1000;
94 FD_ZERO(&fds);
95 FD_SET(cl->pfd, &fds);
96 select(cl->pfd+1, &fds, 0, 0, &tv);
97 rc=0;
98 if (FD_ISSET(cl->pfd, &fds))
99 if (!(rc=reader->ph.recv(cl, buf, l)))
100 rc=-1;
101
102 return(rc);
103}
104
105#define MSTIMEOUT 0x800000
106#define DEFAULT_CONNECT_TIMEOUT 500
107
108int network_select(int forRead, int timeout)
109{
110 int sd = cur_client()->udp_fd;
111 if(sd>=0) {
112 fd_set fds;
113 FD_ZERO(&fds); FD_SET(sd,&fds);
114 struct timeval tv;
115 if(timeout&MSTIMEOUT) { tv.tv_sec=0; tv.tv_usec=(timeout&~MSTIMEOUT)*1000; }
116 else { tv.tv_sec=0; tv.tv_usec=timeout*1000; }
117 int r=select(sd+1,forRead ? &fds:0,forRead ? 0:&fds,0,&tv);
118 if(r>0) return 1;
119 else if(r<0) {
120 cs_debug_mask(D_READER, "socket: select failed: %s",strerror(errno));
121 return -1;
122 }
123 else {
124 if(timeout>0) {
125 cs_debug_mask(D_READER, "socket: select timed out (%d %s)",timeout&~MSTIMEOUT,(timeout&MSTIMEOUT)?"ms":"secs");
126 }
127 errno=ETIMEDOUT;
128 return 0;
129 }
130 }
131 return -1;
132}
133
134// according to documentation getaddrinfo() is thread safe
135int hostResolve(struct s_reader *rdr)
136{
137 int result = 0;
138 struct s_client *cl = rdr->client;
139
140 pthread_mutex_lock(&gethostbyname_lock);
141
142 in_addr_t last_ip = cl->ip;
143
144 if (cfg->resolve_gethostbyname) { //Resolve with gethostbyname:
145 struct hostent *rht = gethostbyname(rdr->device);
146 if (!rht) {
147 cs_log("can't resolve %s", rdr->device);
148 result = 0;
149 } else {
150 memcpy(&cl->udp_sa.sin_addr, rht->h_addr, sizeof(cl->udp_sa.sin_addr));
151 cl->ip=cs_inet_order(cl->udp_sa.sin_addr.s_addr);
152 result = 1;
153 }
154 }
155 else { //Resolve with getaddrinfo:
156 struct addrinfo hints, *res = NULL;
157 memset(&hints, 0, sizeof(hints));
158 hints.ai_socktype = SOCK_STREAM;
159 hints.ai_family = cl->udp_sa.sin_family;
160 hints.ai_protocol = IPPROTO_TCP;
161
162 int err = getaddrinfo(rdr->device, NULL, &hints, &res);
163 if (err != 0 || !res || !res->ai_addr) {
164 cs_log("can't resolve %s, error: %s", rdr->device, err ? gai_strerror(err) : "unknown");
165 result = 0;
166 } else {
167 cl->udp_sa.sin_addr.s_addr = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr;
168 cl->ip = cs_inet_order(cl->udp_sa.sin_addr.s_addr);
169 result = 1;
170 }
171 if (res) freeaddrinfo(res);
172 }
173
174 if (!result) {
175 cl->udp_sa.sin_addr.s_addr = 0;
176 cl->ip = 0;
177 } else if (cl->ip != last_ip) {
178 uchar *ip = (uchar*) &cl->ip;
179 cs_log("%s: resolved ip=%d.%d.%d.%d", rdr->device, ip[3], ip[2], ip[1], ip[0]);
180 }
181
182 pthread_mutex_unlock(&gethostbyname_lock);
183
184 return result;
185}
186
187void clear_block_delay(struct s_reader *rdr) {
188 rdr->tcp_block_delay = 100;
189 cs_ftime(&rdr->tcp_block_connect_till);
190}
191
192void block_connect(struct s_reader *rdr) {
193 if (!rdr->tcp_block_delay)
194 rdr->tcp_block_delay = 100; //starting blocking time, 100ms
195 rdr->tcp_block_connect_till.time += rdr->tcp_block_delay / 1000;
196 rdr->tcp_block_connect_till.millitm += rdr->tcp_block_delay % 1000;
197 rdr->tcp_block_delay *= 2; //increment timeouts
198 if (rdr->tcp_block_delay >= 60*1000)
199 rdr->tcp_block_delay = 60*1000; //max 1min, todo config
200 cs_debug_mask(D_TRACE, "tcp connect blocking delay for %s set to %d", rdr->label, rdr->tcp_block_delay);
201}
202
203int is_connect_blocked(struct s_reader *rdr) {
204 struct timeb cur_time;
205 cs_ftime(&cur_time);
206 return (comp_timeb(&cur_time, &rdr->tcp_block_connect_till) < 0);
207}
208
209int network_tcp_connection_open()
210{
211 struct s_client *cl = cur_client();
212 struct s_reader *rdr = cl->reader;
213 cs_log("connecting to %s", rdr->device);
214
215 in_addr_t last_ip = cl->ip;
216 if (!hostResolve(rdr))
217 return -1;
218
219 if (last_ip != cl->ip) //clean blocking delay on ip change:
220 clear_block_delay(rdr);
221 if (is_connect_blocked(rdr)) { //inside of blocking delay, do not connect!
222 cs_log("tcp connect blocking delay asserted for %s", rdr->label);
223 return -1;
224 }
225
226 int flag = 1;
227 setsockopt(cl->udp_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
228
229 int sd = cl->udp_fd;
230 int fl = fcntl(sd, F_GETFL);
231 fcntl(sd, F_SETFL, O_NONBLOCK); //set to nonblocking mode to avoid "endless" connecting loops and pipe-overflows:
232 int res =connect(sd, (struct sockaddr *)&cl->udp_sa, sizeof(cl->udp_sa));
233 if (res == 0) {
234 fcntl(sd, F_SETFL, fl); //connect sucessfull, restore blocking mode
235 clear_block_delay(rdr);
236 return sd;
237 }
238
239 if (errno == EINPROGRESS || errno == EALREADY) {
240 if (network_select(0, DEFAULT_CONNECT_TIMEOUT) > 0) { //if connect is in progress, wait apr. 500ms
241 int r = -1;
242 uint l = sizeof(r);
243 if (getsockopt(sd, SOL_SOCKET, SO_ERROR, &r, (socklen_t*)&l) == 0) {
244 if (r == 0) {
245 fcntl(sd, F_SETFL, fl);
246 clear_block_delay(rdr);
247 return sd; //now we are connected
248 }
249 }
250 }
251 }
252 //else we are not connected - or already connected:
253 else if (errno == EISCONN) {
254 cs_log("already connected!");
255 fcntl(sd, F_SETFL, fl);
256 clear_block_delay(rdr);
257 return sd;
258 }
259
260 if (errno == EBADF || errno == ENOTSOCK) {
261 cs_log("connect failed: bad socket/descriptor %d", sd);
262 }
263 else if (errno == ETIMEDOUT) {
264 cs_log("connect failed: timeout");
265 }
266 else if (errno == ECONNREFUSED) {
267 cs_log("connection refused");
268 }
269 else if (errno == ENETUNREACH) {
270 cs_log("connect failed: network unreachable!");
271 }
272 else if (errno == EADDRINUSE) {
273 cs_log("connect failed: address in use!");
274 }
275 else
276 cs_log("connect(fd=%d) failed: (errno=%d: %s)", sd, errno, strerror(errno));
277
278 fcntl(sd, F_SETFL, fl); //restore blocking mode
279
280 //connect has failed. Block connect for a while:
281 block_connect(rdr);
282
283 return -1;
284}
285
286void network_tcp_connection_close(struct s_client *cl, int fd)
287{
288 if(!cl) return;
289 struct s_reader *reader = cl->reader;
290 cs_debug_mask(D_READER, "tcp_conn_close(): fd=%d, cl->typ == 'c'=%d", fd, cl->typ == 'c');
291
292 if (fd) {
293 close(fd);
294 if (fd == cl->udp_fd)
295 cl->udp_fd = 0;
296 if (fd == cl->pfd)
297 cl->pfd = 0;
298
299 if(reader)
300 clear_block_delay(reader);
301 }
302
303
304 if (cl->typ != 'c')
305 {
306 int i;
307 //cl->pfd = 0;
308 if(reader)
309 reader->tcp_connected = 0;
310
311 if (cl->ecmtask) {
312 for (i = 0; i < CS_MAXPENDING; i++) {
313 cl->ecmtask[i].idx = 0;
314 cl->ecmtask[i].rc = 0;
315 }
316 }
317
318 if(reader) {
319 reader->ncd_msgid=0;
320 reader->last_s=reader->last_g=0;
321
322 if (reader->ph.c_init(cl)) {
323 cs_debug_mask(D_READER, "network_tcp_connection_close() exit(1);");
324 cs_exit(1);
325 }
326 }
327 }
328}
329
330static void casc_do_sock_log(struct s_reader * reader)
331{
332 int i, idx;
333 ushort caid, srvid;
334 ulong provid;
335 struct s_client *cl = reader->client;
336
337 idx=reader->ph.c_recv_log(&caid, &provid, &srvid);
338 cl->last=time((time_t)0);
339 if (idx<0) return; // no dcw-msg received
340
341 for (i=0; i<CS_MAXPENDING; i++)
342 {
343 if ( (cl->ecmtask[i].rc>=10)
344 && (cl->ecmtask[i].idx==idx)
345 && (cl->ecmtask[i].caid==caid)
346 && (cl->ecmtask[i].prid==provid)
347 && (cl->ecmtask[i].srvid==srvid))
348 {
349 casc_check_dcw(reader, i, 0, cl->ecmtask[i].cw); // send "not found"
350 break;
351 }
352 }
353}
354
355static void casc_do_sock(struct s_reader * reader, int w)
356{
357 int i, n, idx, rc, j;
358 uchar buf[1024];
359 uchar dcw[16];
360 struct s_client *cl = reader->client;
361
362 if ((n=casc_recv_timer(reader, buf, sizeof(buf), w))<=0)
363 {
364 if (reader->ph.type==MOD_CONN_TCP && reader->typ != R_RADEGAST)
365 {
366 if (reader->ph.c_idle)
367 reader_do_idle(reader);
368 else {
369 cs_debug_mask(D_READER, "casc_do_sock: close connection");
370 network_tcp_connection_close(reader->client, cl->udp_fd);
371 }
372 return;
373 }
374 }
375 cl->last=time((time_t)0);
376 idx=reader->ph.c_recv_chk(cl, dcw, &rc, buf, n);
377
378 if (idx<0) return; // no dcw received
379 reader->last_g=time((time_t*)0); // for reconnect timeout
380//cs_log("casc_do_sock: last_s=%d, last_g=%d", reader->last_s, reader->last_g);
381 if (!idx) idx=cl->last_idx;
382 j=0;
383 for (i=0; i<CS_MAXPENDING; i++)
384 {
385
386 if (cl->ecmtask[i].idx==idx)
387 {
388 casc_check_dcw(reader, i, rc, dcw);
389 j=1;
390 break;
391 }
392 }
393}
394
395static void casc_get_dcw(struct s_reader * reader, int n)
396{
397 int w;
398 struct timeb tps, tpe;
399 struct s_client *cl = reader->client;
400 tpe=cl->ecmtask[n].tps;
401 //tpe.millitm+=1500; // TODO: timeout of 1500 should be config
402
403 tpe.time += cfg->srtimeout/1000;
404 tpe.millitm += cfg->srtimeout%1000;
405
406 cs_ftime(&tps);
407 while (((w=1000*(tpe.time-tps.time)+tpe.millitm-tps.millitm)>0)
408 && (cl->ecmtask[n].rc>=10))
409 {
410 casc_do_sock(reader, w);
411 cs_ftime(&tps);
412 }
413 if (cl->ecmtask[n].rc>=10)
414 casc_check_dcw(reader, n, 0, cl->ecmtask[n].cw); // simulate "not found"
415}
416
417
418
419int casc_process_ecm(struct s_reader * reader, ECM_REQUEST *er)
420{
421 int rc, n, i, sflag;
422 time_t t;//, tls;
423 struct s_client *cl = reader->client;
424
425 uchar buf[512];
426
427 t=time((time_t *)0);
428 for (n=-1, i=0, sflag=1; i<CS_MAXPENDING; i++)
429 {
430 if ((t-(ulong)cl->ecmtask[i].tps.time > ((cfg->ctimeout + 500) / 1000) + 1) &&
431 (cl->ecmtask[i].rc>=10)) // drop timeouts
432 {
433 cl->ecmtask[i].rc=0;
434 }
435 if (n<0 && (cl->ecmtask[i].rc<10)) // free slot found
436 n=i;
437 if ((cl->ecmtask[i].rc>=10) && // ecm already pending
438 (!memcmp(er->ecmd5, cl->ecmtask[i].ecmd5, CS_ECMSTORESIZE)) &&
439 (er->level<=cl->ecmtask[i].level)) // ... this level at least
440 sflag=0;
441 }
442 if (n<0)
443 {
444 cs_log("WARNING: ecm pending table overflow !!");
445 return(-2);
446 }
447 memcpy(&cl->ecmtask[n], er, sizeof(ECM_REQUEST));
448 if( reader->typ == R_NEWCAMD )
449 cl->ecmtask[n].idx=(reader->ncd_msgid==0)?2:reader->ncd_msgid+1;
450 else
451 cl->ecmtask[n].idx=cl->idx++;
452 cl->ecmtask[n].rc=10;
453 cs_debug_mask(D_READER, "---- ecm_task %d, idx %d, sflag=%d, level=%d",
454 n, cl->ecmtask[n].idx, sflag, er->level);
455
456 if( reader->ph.type==MOD_CONN_TCP && reader->tcp_rto )
457 {
458 int rto = abs(reader->last_s - reader->last_g);
459 if (rto >= (reader->tcp_rto*60))
460 {
461 if (reader->ph.c_idle)
462 reader_do_idle(reader);
463 else {
464 cs_debug_mask(D_READER, "rto=%d", rto);
465 network_tcp_connection_close(reader->client, cl->udp_fd);
466 }
467 }
468 }
469
470 cs_ddump_mask(D_ATR, er->ecm, er->l, "casc ecm:");
471 rc=0;
472 if (sflag)
473 {
474 if ((rc=reader->ph.c_send_ecm(cl, &cl->ecmtask[n], buf)))
475 casc_check_dcw(reader, n, 0, cl->ecmtask[n].cw); // simulate "not found"
476 else
477 cl->last_idx = cl->ecmtask[n].idx;
478 reader->last_s = t; // used for inactive_timeout and reconnect_timeout in TCP reader
479
480 if (!reader->ph.c_multi)
481 casc_get_dcw(reader, n);
482 }
483
484//cs_log("casc_process_ecm 1: last_s=%d, last_g=%d", reader->last_s, reader->last_g);
485
486 if (cl->idx>0x1ffe) cl->idx=1;
487 return(rc);
488}
489
490static int reader_store_emm(uchar *emm, uchar type)
491{
492 int rc;
493 struct s_client *cl = cur_client();
494 memcpy(cl->emmcache[cl->rotate].emmd5, MD5(emm, emm[2], cl->dump), CS_EMMSTORESIZE);
495 cl->emmcache[cl->rotate].type=type;
496 cl->emmcache[cl->rotate].count=1;
497// cs_debug_mask(D_READER, "EMM stored (index %d)", rotate);
498 rc=cl->rotate;
499 cl->rotate=(++cl->rotate < CS_EMMCACHESIZE)?cl->rotate:0;
500 return(rc);
501}
502
503static void reader_get_ecm(struct s_reader * reader, ECM_REQUEST *er)
504{
505 //cs_log("hallo idx:%d rc:%d caid:%04X",er->idx,er->rc,er->caid);
506 if ((er->rc<10) )
507 {
508 send_dcw(reader->client, er);
509 return;
510 }
511
512 er->ocaid=er->caid;
513 if (!chk_bcaid(er, &reader->ctab))
514 {
515 cs_debug_mask(D_READER, "caid %04X filtered", er->caid);
516 er->rcEx=E2_CAID;
517 er->rc=0;
518 write_ecm_answer(reader, er);
519 return;
520 }
521 // cache2
522 if (check_cwcache2(er, er->client->grp))
523 {
524 er->rc=2;
525 write_ecm_answer(reader, er);
526 return;
527 }
528 if (reader->typ & R_IS_CASCADING)
529 {
530 struct s_client *cl = reader->client;
531 cl->last_srvid=er->srvid;
532 cl->last_caid=er->caid;
533 casc_process_ecm(reader, er);
534 return;
535 }
536#ifdef WITH_CARDREADER
537 if (reader->ratelimitecm) {
538 cs_debug_mask(D_READER, "ratelimit idx:%d rc:%d caid:%04X srvid:%04X",er->idx,er->rc,er->caid,er->srvid);
539 int foundspace=-1;
540 int h;
541 for (h=0;h<reader->ratelimitecm;h++) {
542 if (reader->rlecmh[h].srvid == er->srvid) {
543 foundspace=h;
544 cs_debug_mask(D_READER, "ratelimit found srvid in use at pos: %d",h);
545 break;
546 }
547 }
548 if (foundspace<0) {
549 for (h=0;h<reader->ratelimitecm;h++) {
550 if ((reader->rlecmh[h].last ==- 1) || ((time(NULL)-reader->rlecmh[h].last) > reader->ratelimitseconds)) {
551 foundspace=h;
552 cs_debug_mask(D_READER, "ratelimit found space at pos: %d old seconds %d",h,reader->rlecmh[h].last);
553 break;
554 }
555 }
556 }
557 if (foundspace<0) {
558 //drop
559 cs_debug_mask(D_READER, "ratelimit could not find space for srvid %04X. Dropping.",er->srvid);
560 er->rcEx=32;
561 er->rc=0;
562 int clcw;
563 for (clcw=0;clcw<16;clcw++) er->cw[clcw]=(uchar)0;
564 snprintf( er->msglog, MSGLOGSIZE, "ECMratelimit no space for srvid" );
565 write_ecm_answer(reader, er);
566 return;
567 } else {
568 reader->rlecmh[foundspace].last=time(NULL);
569 reader->rlecmh[foundspace].srvid=er->srvid;
570 }
571
572 }
573 cs_ddump_mask(D_ATR, er->ecm, er->l, "ecm:");
574 er->msglog[0] = 0;
575 struct timeb tps, tpe;
576 cs_ftime(&tps);
577 er->rc=reader_ecm(reader, er);
578 cs_ftime(&tpe);
579 if (cs_dblevel) {
580 ushort lc, *lp;
581 for (lp=(ushort *)er->ecm+(er->l>>2), lc=0; lp>=(ushort *)er->ecm; lp--)
582 lc^=*lp;
583 cs_debug_mask(D_TRACE, "reader: %s ecm: %04X real time: %d ms", reader->label, lc, 1000*(tpe.time-tps.time)+tpe.millitm-tps.millitm);
584 }
585 write_ecm_answer(reader, er);
586 reader_post_process(reader);
587#endif
588 //fixme re-activated code for testing
589 if(reader->typ=='r') reader->qlen--;
590 //printf("queue: %d\n",reader->qlen);
591}
592
593static int reader_do_emm(struct s_reader * reader, EMM_PACKET *ep)
594{
595 int i, no, rc, ecs;
596 char *rtxt[] = { "error", (reader->typ & R_IS_CASCADING) ? "sent" : "written", "skipped", "blocked" };
597 char *typedesc[]= { "unknown", "unique", "shared", "global" };
598 struct timeb tps, tpe;
599 struct s_client *cl = reader->client;
600
601 cs_ftime(&tps);
602
603 MD5(ep->emm, ep->emm[2], cl->dump);
604
605 no=0;
606 for (i=ecs=0; (i<CS_EMMCACHESIZE) && (!ecs); i++) {
607 if (!memcmp(cl->emmcache[i].emmd5, cl->dump, CS_EMMSTORESIZE)) {
608 if (reader->cachemm)
609 ecs=(reader->rewritemm > cl->emmcache[i].count) ? 1 : 2;
610 else
611 ecs=1;
612 no=++cl->emmcache[i].count;
613 i--;
614 }
615 }
616
617 if ((rc=ecs)<2)
618 {
619 if (reader->typ & R_IS_CASCADING) {
620 cs_debug_mask(D_READER, "network emm reader: %s" ,reader->label);
621
622 if (reader->ph.c_send_emm) {
623 rc=reader->ph.c_send_emm(ep);
624 } else {
625 cs_debug_mask(D_READER, "send_emm() support missing");
626 rc=0;
627 }
628 } else {
629 cs_debug_mask(D_READER, "local emm reader: %s" ,reader->label);
630#ifdef WITH_CARDREADER
631 rc=reader_emm(reader, ep);
632#else
633 rc=0;
634#endif
635 }
636
637 if (!ecs)
638 {
639 i=reader_store_emm(ep->emm, ep->type);
640 no=1;
641 }
642 }
643
644 if (rc) cl->lastemm=time((time_t)0);
645
646#ifdef CS_LED
647 if (rc) cs_switch_led(LED3, LED_BLINK_ON);
648#endif
649
650 if (reader->logemm & (1 << rc))
651 {
652 cs_ftime(&tpe);
653
654 cs_log("%s emmtype=%s, len=%d, idx=%d, cnt=%d: %s (%d ms) by %s",
655 username(ep->client), typedesc[cl->emmcache[i].type], ep->emm[2],
656 i, no, rtxt[rc], 1000*(tpe.time-tps.time)+tpe.millitm-tps.millitm, reader->label); //FIXME not sure why emmtyp must come from ep->client and typedesc can be of cur_client
657 }
658
659#ifdef WEBIF
660 //counting results
661 switch(rc){
662 case 0:
663 reader->emmerror[ep->type]++;
664 break;
665 case 1:
666 reader->emmwritten[ep->type]++;
667 break;
668 case 2:
669 reader->emmskipped[ep->type]++;
670 break;
671 case 3:
672 reader->emmblocked[ep->type]++;
673 break;
674 }
675#endif
676
677#ifdef QBOXHD_LED
678 if (rc) qboxhd_led_blink(QBOXHD_LED_COLOR_BLUE,QBOXHD_LED_BLINK_MEDIUM);
679#endif
680
681
682 return(rc);
683}
684
685static int reader_listen(struct s_reader * reader, int fd1, int fd2)
686{
687 int fdmax, tcp_toflag, use_tv=(!(reader->typ & R_IS_CASCADING));
688 int is_tcp=(reader->ph.type==MOD_CONN_TCP);
689 fd_set fds;
690 struct timeval tv;
691
692#ifdef CS_WITH_GBOX
693 if(reader->typ==R_GBOX) {
694 struct timeb tpe;
695 int x;
696 ulong ms;
697 cs_ftime(&tpe);
698 for(x=0;x<CS_MAXPENDING;x++){
699 ms=1000*(tpe.time-cl->ecmtask[x].tps.time)+tpe.millitm-cl->ecmtask[x].tps.millitm;
700 if(cl->ecmtask[x].rc == 10 && ms > cfg->ctimeout && cl->ridx == cl->ecmtask[x].gbxRidx) {
701 //cs_log("hello rc=%d idx:%d x:%d ridx%d ridx:%d",cl->ecmtask[x].rc,cl->ecmtask[x].idx,x,ridx,cl->ecmtask[x].gbxRidx);
702 cl->ecmtask[x].rc=5;
703 send_dcw(cl, &cl->ecmtask[x]);
704 }
705 }
706 }
707#endif
708
709 tcp_toflag=(fd2 && is_tcp && reader->tcp_ito && reader->tcp_connected);
710 tv.tv_sec = 0;
711 tv.tv_usec = 100000L;
712 if (tcp_toflag)
713 {
714 tv.tv_sec = reader->tcp_ito*60;
715 tv.tv_usec = 0;
716 use_tv = 1;
717 }
718 FD_ZERO(&fds);
719 FD_SET(fd1, &fds);
720 if (fd2) FD_SET(fd2, &fds);
721 if (logfd) FD_SET(logfd, &fds);
722 fdmax=(fd1>fd2) ? fd1 : fd2;
723 fdmax=(fdmax>logfd) ? fdmax : logfd;
724 if (select(fdmax+1, &fds, 0, 0, (use_tv) ? &tv : 0)<0) return(0);
725
726 if ((logfd) && (FD_ISSET(logfd, &fds)))
727 {
728 cs_debug_mask(D_READER, "select: log-socket ist set");
729 return(3);
730 }
731
732 if ((fd2) && (FD_ISSET(fd2, &fds)))
733 {
734 cs_debug_mask(D_READER, "select: socket is set");
735 return(2);
736 }
737
738 if (FD_ISSET(fd1, &fds))
739 {
740 if (tcp_toflag)
741 {
742 time_t now;
743 int time_diff;
744 time(&now);
745 time_diff = abs(now-reader->last_s);
746 if (time_diff>(reader->tcp_ito*60))
747 {
748 if (reader->ph.c_idle)
749 reader_do_idle(reader);
750 else {
751 cs_debug_mask(D_READER, "%s inactive_timeout (%d), close connection (fd=%d)",
752 reader->ph.desc, time_diff, fd2);
753 network_tcp_connection_close(reader->client, fd2);
754 }
755 }
756 }
757 cs_debug_mask(D_READER, "select: pipe is set");
758 return(1);
759 }
760
761 if (tcp_toflag)
762 {
763 if (reader->ph.c_idle)
764 reader_do_idle(reader);
765 else {
766 cs_debug_mask(D_READER, "%s inactive_timeout (%d), close connection (fd=%d)",
767 reader->ph.desc, tv.tv_sec, fd2);
768 network_tcp_connection_close(reader->client, fd2);
769 }
770 return(0);
771 }
772
773#ifdef WITH_CARDREADER
774 if (!(reader->typ & R_IS_CASCADING)) reader_checkhealth(reader);
775#endif
776 return(0);
777}
778
779void reader_do_card_info(struct s_reader * reader)
780{
781#ifdef WITH_CARDREADER
782 reader_card_info(reader);
783#endif
784 if (reader->ph.c_card_info)
785 reader->ph.c_card_info();
786}
787
788void clear_reader_pipe(struct s_reader * reader)
789{
790 uchar *ptr;
791 int pipeCmd;
792 while (reader && reader->client && reader->client->fd_m2c_c)
793 {
794 pipeCmd = read_from_pipe(reader->client->fd_m2c_c, &ptr, 0);
795 if (ptr) free(ptr);
796 if (pipeCmd==PIP_ID_ERR || pipeCmd==PIP_ID_NUL)
797 break;
798 }
799}
800
801static void reader_do_pipe(struct s_reader * reader)
802{
803 uchar *ptr;
804 int pipeCmd = read_from_pipe(reader->client->fd_m2c_c, &ptr, 0);
805
806 switch(pipeCmd)
807 {
808 case PIP_ID_ECM:
809 reader_get_ecm(reader, (ECM_REQUEST *)ptr);
810 break;
811 case PIP_ID_EMM:
812 reader_do_emm(reader, (EMM_PACKET *)ptr);
813 break;
814 case PIP_ID_CIN:
815 reader_do_card_info(reader);
816 break;
817 case PIP_ID_ERR:
818 cs_exit(1);
819 break;
820 default:
821 cs_log("unhandled pipe message %d (reader %s)", pipeCmd, reader->label);
822 break;
823 }
824 if (ptr) free(ptr);
825}
826
827void reader_do_idle(struct s_reader * reader)
828{
829 if (reader->ph.c_idle)
830 reader->ph.c_idle();
831}
832
833static void reader_main(struct s_reader * reader)
834{
835 while (1)
836 {
837 switch(reader_listen(reader, reader->client->fd_m2c_c, reader->client->pfd))
838 {
839 case 0: reader_do_idle(reader); break;
840 case 1: reader_do_pipe(reader) ; break;
841 case 2: casc_do_sock(reader, 0) ; break;
842 case 3: casc_do_sock_log(reader); break;
843 }
844 }
845}
846
847void * start_cardreader(void * rdr)
848{
849 struct s_reader * reader = (struct s_reader *) rdr;
850
851 reader->client->thread=pthread_self();
852 pthread_setspecific(getclient, reader->client);
853 strcpy(reader->client->usr, first_client->usr);
854
855 if (reader->typ & R_IS_CASCADING)
856 {
857 reader->client->typ='p';
858 reader->client->port=reader->r_port;
859 strcpy(reader->client->usr, reader->r_usr);
860 cs_log("proxy thread started (thread=%8X, label=%s, server=%s)",pthread_self(), reader->label, reader->device);
861
862 if (!(reader->ph.c_init)) {
863 cs_log("FATAL: %s-protocol not supporting cascading", reader->ph.desc);
864 cs_sleepms(1000);
865 cs_exit(1);
866 }
867
868 if (reader->ph.c_init(reader->client)) {
869 //proxy reader start failed
870 cs_exit(1);
871 }
872
873 if ((reader->log_port) && (reader->ph.c_init_log))
874 reader->ph.c_init_log();
875 }
876#ifdef WITH_CARDREADER
877 else
878 {
879 reader->client->ip=cs_inet_addr("127.0.0.1");
880 cs_log("reader thread started (thread=%8X, label=%s, device=%s, detect=%s%s, mhz=%d, cardmhz=%d)", pthread_self(), reader->label,
881 reader->device, reader->detect&0x80 ? "!" : "",RDR_CD_TXT[reader->detect&0x7f], reader->mhz,reader->cardmhz);
882 while (reader_device_init(reader)==2)
883 cs_sleepms(60000); // wait 60 secs and try again
884 }
885
886#endif
887 reader->client->emmcache=(struct s_emm *)malloc(CS_EMMCACHESIZE*(sizeof(struct s_emm)));
888 if (!reader->client->emmcache)
889 {
890 cs_log("Cannot allocate memory (errno=%d)", errno);
891 cs_exit(1);
892 }
893 memset(reader->client->emmcache, 0, CS_EMMCACHESIZE*(sizeof(struct s_emm)));
894
895 reader->client->ecmtask=(ECM_REQUEST *)malloc(CS_MAXPENDING*(sizeof(ECM_REQUEST)));
896 if (!reader->client->ecmtask)
897 {
898 cs_log("Cannot allocate memory (errno=%d)", errno);
899 cs_exit(1);
900 }
901 memset(reader->client->ecmtask, 0, CS_MAXPENDING*(sizeof(ECM_REQUEST)));
902 reader_main(reader);
903 cs_exit(0);
904 return NULL; //dummy to prevent compiler error
905}
906
Note: See TracBrowser for help on using the repository browser.