source: trunk/oscam-reader.c@ 6610

Last change on this file since 6610 was 6610, checked in by corsair, 11 years ago

emm cache fixed

File size: 21.6 KB
Line 
1#include "globals.h"
2#include "reader-common.h"
3#include "csctapi/ifd_sc8in1.h"
4
5int32_t logfd = 0;
6
7void reader_do_idle(struct s_reader * reader);
8
9void cs_ri_brk(struct s_reader * reader, int32_t flag)
10{
11 if (flag)
12 reader->brk_pos=reader->init_history_pos;
13 else
14 reader->init_history_pos=reader->brk_pos;
15}
16
17void cs_ri_log(struct s_reader * reader, char *fmt,...)
18{
19 char txt[256];
20
21 va_list params;
22 va_start(params, fmt);
23 vsnprintf(txt, sizeof(txt), fmt, params);
24 va_end(params);
25 cs_log("%s", txt);
26
27 if (cfg.saveinithistory) {
28 int32_t size = reader->init_history_pos+strlen(txt)+2;
29
30 cs_realloc(&reader->init_history, size, -1);
31
32 if (!reader->init_history)
33 return;
34
35 snprintf(reader->init_history+reader->init_history_pos, strlen(txt)+2, "%s\n", txt);
36 reader->init_history_pos+=strlen(txt)+1;
37 }
38}
39
40/**
41 * add one entitlement item to entitlements of reader.
42 **/
43void cs_add_entitlement(struct s_reader *rdr, uint16_t caid, uint32_t provid, uint64_t id, uint32_t class, time_t start, time_t end, uint8_t type)
44{
45 if (!rdr->ll_entitlements) rdr->ll_entitlements = ll_create("ll_entitlements");
46
47 S_ENTITLEMENT *item;
48 if(cs_malloc(&item,sizeof(S_ENTITLEMENT), -1)){
49
50 // fill item
51 item->caid = caid;
52 item->provid = provid;
53 item->id = id;
54 item->class = class;
55 item->start = start;
56 item->end = end;
57 item->type = type;
58
59 //add item
60 ll_append(rdr->ll_entitlements, item);
61
62 // cs_debug_mask(D_TRACE, "entitlement: Add caid %4X id %4X %s - %s ", item->caid, item->id, item->start, item->end);
63 }
64
65}
66
67/**
68 * clears entitlements of reader.
69 **/
70void cs_clear_entitlement(struct s_reader *rdr)
71{
72 if (!rdr->ll_entitlements)
73 return;
74
75 ll_clear_data(rdr->ll_entitlements);
76}
77
78
79void casc_check_dcw(struct s_reader * reader, int32_t idx, int32_t rc, uchar *cw)
80{
81 int32_t i, pending=0;
82 time_t t = time(NULL);
83 ECM_REQUEST *ecm;
84 struct s_client *cl = reader->client;
85
86 if(!cl) return;
87
88 for (i=0; i<CS_MAXPENDING; i++) {
89 ecm = &cl->ecmtask[i];
90 if ((ecm->rc>=10) && ecm->caid == cl->ecmtask[idx].caid && (!memcmp(ecm->ecmd5, cl->ecmtask[idx].ecmd5, CS_ECMSTORESIZE))) {
91 if (rc) {
92 //write_ecm_answer(reader, ecm->parent, (i==idx) ? E_FOUND : E_CACHE2, 0, cw, NULL); //Cache2 now generated by distribute_ecm
93 write_ecm_answer(reader, ecm->parent, E_FOUND, 0, cw, NULL);
94 } else
95 write_ecm_answer(reader, ecm->parent, E_NOTFOUND, 0 , NULL, NULL);
96 ecm->idx=0;
97 ecm->rc=0;
98 }
99
100 if (ecm->rc>=10 && (t-(uint32_t)ecm->tps.time > ((cfg.ctimeout + 500) / 1000) + 1)) { // drop timeouts
101 ecm->rc=0;
102#ifdef WITH_LB
103 send_reader_stat(reader, ecm, NULL, E_TIMEOUT);
104#endif
105 }
106
107 if (ecm->rc >= 10)
108 pending++;
109 }
110 cl->pending=pending;
111}
112
113int32_t hostResolve(struct s_reader *rdr){
114 struct s_client *cl = rdr->client;
115
116 if(!cl) return 0;
117
118 in_addr_t last_ip = cl->ip;
119 cl->ip = cs_getIPfromHost(rdr->device);
120 cl->udp_sa.sin_addr.s_addr = cl->ip;
121
122 if (cl->ip != last_ip) {
123 cs_log("%s: resolved ip=%s", rdr->device, cs_inet_ntoa(cl->ip));
124 }
125
126 return cl->ip?1:0;
127}
128
129void clear_block_delay(struct s_reader *rdr) {
130 rdr->tcp_block_delay = 0;
131 cs_ftime(&rdr->tcp_block_connect_till);
132}
133
134void block_connect(struct s_reader *rdr) {
135 if (!rdr->tcp_block_delay)
136 rdr->tcp_block_delay = 100; //starting blocking time, 100ms
137 cs_ftime(&rdr->tcp_block_connect_till);
138 rdr->tcp_block_connect_till.time += rdr->tcp_block_delay / 1000;
139 rdr->tcp_block_connect_till.millitm += rdr->tcp_block_delay % 1000;
140 rdr->tcp_block_delay *= 4; //increment timeouts
141 if (rdr->tcp_block_delay >= 60*1000)
142 rdr->tcp_block_delay = 60*1000; //max 1min, todo config
143 cs_debug_mask(D_TRACE, "tcp connect blocking delay for %s set to %d", rdr->label, rdr->tcp_block_delay);
144}
145
146int32_t is_connect_blocked(struct s_reader *rdr) {
147 struct timeb cur_time;
148 cs_ftime(&cur_time);
149 int32_t blocked = (rdr->tcp_block_delay && comp_timeb(&cur_time, &rdr->tcp_block_connect_till) < 0);
150 if (blocked) {
151 int32_t time = 1000*(rdr->tcp_block_connect_till.time-cur_time.time)
152 +rdr->tcp_block_connect_till.millitm-cur_time.millitm;
153 cs_log("%s connection blocked, retrying in %ds", rdr->label, time/1000);
154 }
155 return blocked;
156}
157
158int32_t network_tcp_connection_open(struct s_reader *rdr)
159{
160 if (!rdr) return -1;
161 struct s_client *client = rdr->client;
162 struct sockaddr_in loc_sa;
163
164 memset((char *)&client->udp_sa, 0, sizeof(client->udp_sa));
165
166 in_addr_t last_ip = client->ip;
167 if (!hostResolve(rdr))
168 return -1;
169
170 if (last_ip != client->ip) //clean blocking delay on ip change:
171 clear_block_delay(rdr);
172
173 if (is_connect_blocked(rdr)) { //inside of blocking delay, do not connect!
174 return -1;
175 }
176
177 if (client->reader->r_port<=0) {
178 cs_log("invalid port %d for server %s", client->reader->r_port, client->reader->device);
179 return -1;
180 }
181
182 client->is_udp=(rdr->typ==R_CAMD35);
183
184 cs_log("connecting to %s on %s:%d", rdr->label, rdr->device, rdr->r_port);
185
186 if (client->udp_fd)
187 cs_log("WARNING: client->udp_fd was not 0");
188
189 if ((client->udp_fd=socket(PF_INET, client->is_udp ? SOCK_DGRAM : SOCK_STREAM, client->is_udp ? IPPROTO_UDP : IPPROTO_TCP))<0) {
190 cs_log("Socket creation failed (errno=%d %s)", errno, strerror(errno));
191 client->udp_fd = 0;
192 block_connect(rdr);
193 return -1;
194 }
195
196#ifdef SO_PRIORITY
197 if (cfg.netprio)
198 setsockopt(client->udp_fd, SOL_SOCKET, SO_PRIORITY, (void *)&cfg.netprio, sizeof(uintptr_t));
199#endif
200
201 int32_t keep_alive = 1;
202 setsockopt(client->udp_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keep_alive, sizeof(keep_alive));
203
204 int32_t flag = 1;
205 setsockopt(client->udp_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&flag, sizeof(flag));
206
207 if (client->reader->l_port>0) {
208 memset((char *)&loc_sa,0,sizeof(loc_sa));
209 loc_sa.sin_family = AF_INET;
210 if (cfg.srvip)
211 loc_sa.sin_addr.s_addr = cfg.srvip;
212 else
213 loc_sa.sin_addr.s_addr = INADDR_ANY;
214
215 loc_sa.sin_port = htons(client->reader->l_port);
216 if (bind(client->udp_fd, (struct sockaddr *)&loc_sa, sizeof (loc_sa))<0) {
217 cs_log("bind failed (errno=%d %s)", errno, strerror(errno));
218 close(client->udp_fd);
219 client->udp_fd = 0;
220 block_connect(rdr);
221 return -1;
222 }
223 }
224
225 client->udp_sa.sin_family = AF_INET;
226 client->udp_sa.sin_port = htons((uint16_t)client->reader->r_port);
227
228 cs_log("socket open for %s fd=%d", rdr->ph.desc, client->udp_fd);
229
230 if (client->is_udp) {
231 rdr->tcp_connected = 1;
232 return client->udp_fd;
233 }
234
235 int32_t fl = fcntl(client->udp_fd, F_GETFL);
236 fcntl(client->udp_fd, F_SETFL, O_NONBLOCK);
237
238 int32_t res = connect(client->udp_fd, (struct sockaddr *)&client->udp_sa, sizeof(client->udp_sa));
239 if (res == -1) {
240 int32_t r = -1;
241 if (errno == EINPROGRESS || errno == EALREADY) {
242 struct pollfd pfd;
243 pfd.fd = client->udp_fd;
244 pfd.events = POLLOUT;
245 int32_t rc = poll(&pfd, 1, 3000);
246 if (rc > 0) {
247 uint32_t l = sizeof(r);
248 if (getsockopt(client->udp_fd, SOL_SOCKET, SO_ERROR, &r, (socklen_t*)&l) != 0)
249 r = -1;
250 else
251 errno = r;
252 } else {
253 errno = ETIMEDOUT;
254 }
255 }
256 if (r != 0) {
257 cs_log("connect(fd=%d) failed: (errno=%d %s)", client->udp_fd, errno, strerror(errno));
258 block_connect(rdr); //connect has failed. Block connect for a while
259 close(client->udp_fd);
260 client->udp_fd = 0;
261 return -1;
262 }
263 }
264
265 fcntl(client->udp_fd, F_SETFL, fl); //restore blocking mode
266
267 setTCPTimeouts(client->udp_fd);
268 clear_block_delay(rdr);
269 client->last=client->login=time((time_t*)0);
270 client->last_caid=client->last_srvid=0;
271 client->pfd = client->udp_fd;
272 rdr->tcp_connected = 1;
273 cs_log("connect succesfull %s fd=%d", rdr->ph.desc, client->udp_fd);
274 return client->udp_fd;
275}
276
277void network_tcp_connection_close(struct s_reader *reader, char *reason)
278{
279 if (!reader) {
280 //only proxy reader should call this, client connections are closed on thread cleanup
281 cs_log("WARNING: invalid client tcp_conn_close()");
282 cs_disconnect_client(cur_client());
283 return;
284 }
285
286 struct s_client *cl = reader->client;
287 if(!cl) return;
288 int32_t fd = cl->udp_fd;
289
290 int32_t i;
291
292 if (fd) {
293 cs_log("tcp_conn_close(): fd=%d, cl->typ == '%c' is_udp %d label == '%s' reason %s",
294 fd, cl->typ, cl->is_udp, reader->label, reason?reason:"undef");
295 close(fd);
296
297 cl->udp_fd = 0;
298 cl->pfd = 0;
299 }
300
301 reader->tcp_connected = 0;
302 reader->card_status = UNKNOWN;
303
304 if (cl->ecmtask) {
305 for (i = 0; i < CS_MAXPENDING; i++) {
306 cl->ecmtask[i].idx = 0;
307 cl->ecmtask[i].rc = 0;
308 }
309 }
310}
311
312void casc_do_sock_log(struct s_reader * reader)
313{
314 int32_t i, idx;
315 uint16_t caid, srvid;
316 uint32_t provid;
317 struct s_client *cl = reader->client;
318
319 if(!cl) return;
320
321 idx=reader->ph.c_recv_log(&caid, &provid, &srvid);
322 cl->last=time((time_t*)0);
323 if (idx<0) return; // no dcw-msg received
324
325 if(!cl->ecmtask) {
326 cs_log("WARNING: casc_do_sock_log: ecmtask not a available");
327 return;
328 }
329
330 for (i=0; i<CS_MAXPENDING; i++)
331 {
332 if ( (cl->ecmtask[i].rc>=10)
333 && (cl->ecmtask[i].idx==idx)
334 && (cl->ecmtask[i].caid==caid)
335 && (cl->ecmtask[i].prid==provid)
336 && (cl->ecmtask[i].srvid==srvid))
337 {
338 casc_check_dcw(reader, i, 0, cl->ecmtask[i].cw); // send "not found"
339 break;
340 }
341 }
342}
343
344int32_t casc_process_ecm(struct s_reader * reader, ECM_REQUEST *er)
345{
346 int32_t rc, n, i, sflag, pending=0;
347 time_t t;//, tls;
348 struct s_client *cl = reader->client;
349
350 if(!cl || !cl->ecmtask) {
351 cs_log("WARNING: casc_process_ecm: ecmtask not a available");
352 return -1;
353 }
354
355 uchar buf[512];
356
357 t=time((time_t *)0);
358 ECM_REQUEST *ecm;
359 for (i=0; i<CS_MAXPENDING; i++) {
360 ecm = &cl->ecmtask[i];
361 if ((ecm->rc>=10) && (t-(uint32_t)ecm->tps.time > ((cfg.ctimeout + 500) / 1000) + 1)) { // drop timeouts
362 ecm->rc=0;
363#ifdef WITH_LB
364 send_reader_stat(reader, ecm, NULL, E_TIMEOUT);
365#endif
366 }
367 }
368
369 for (n=-1, i=0, sflag=1; i<CS_MAXPENDING; i++) {
370 ecm = &cl->ecmtask[i];
371 if (n<0 && (ecm->rc<10)) // free slot found
372 n=i;
373
374 // ecm already pending
375 // ... this level at least
376 if ((ecm->rc>=10) && er->caid == ecm->caid && (!memcmp(er->ecmd5, ecm->ecmd5, CS_ECMSTORESIZE)) && (er->level<=ecm->level))
377 sflag=0;
378
379 if (ecm->rc >=10)
380 pending++;
381 }
382 cl->pending=pending;
383
384 if (n<0) {
385 cs_log("WARNING: reader ecm pending table overflow !!");
386 return(-2);
387 }
388
389 memcpy(&cl->ecmtask[n], er, sizeof(ECM_REQUEST));
390 cl->ecmtask[n].matching_rdr = NULL; //This avoids double free of matching_rdr!
391#ifdef CS_CACHEEX
392 cl->ecmtask[n].csp_lastnodes = NULL; //This avoids double free of csp_lastnodes!
393#endif
394 cl->ecmtask[n].parent = er;
395
396 if( reader->typ == R_NEWCAMD )
397 cl->ecmtask[n].idx=(cl->ncd_msgid==0)?2:cl->ncd_msgid+1;
398 else {
399 if (!cl->idx)
400 cl->idx = 1;
401 cl->ecmtask[n].idx=cl->idx++;
402 }
403
404 cl->ecmtask[n].rc=10;
405 cs_debug_mask(D_TRACE, "---- ecm_task %d, idx %d, sflag=%d, level=%d", n, cl->ecmtask[n].idx, sflag, er->level);
406
407 cs_ddump_mask(D_ATR, er->ecm, er->l, "casc ecm:");
408 rc=0;
409 if (sflag) {
410 if ((rc=reader->ph.c_send_ecm(cl, &cl->ecmtask[n], buf)))
411 casc_check_dcw(reader, n, 0, cl->ecmtask[n].cw); // simulate "not found"
412 else
413 cl->last_idx = cl->ecmtask[n].idx;
414 reader->last_s = t; // used for inactive_timeout and reconnect_timeout in TCP reader
415 }
416
417 if (cl->idx>0x1ffe) cl->idx=1;
418
419 return(rc);
420}
421
422static int32_t reader_store_emm(uchar type, uchar *emmd5)
423{
424 int32_t rc;
425 struct s_client *cl = cur_client();
426 memcpy(cl->emmcache[cl->rotate].emmd5, emmd5, CS_EMMSTORESIZE);
427 cl->emmcache[cl->rotate].type=type;
428 cl->emmcache[cl->rotate].count=1;
429// cs_debug_mask(D_READER, "EMM stored (index %d)", rotate);
430 rc=cl->rotate;
431 cl->rotate=(++cl->rotate < CS_EMMCACHESIZE)?cl->rotate:0;
432 return(rc);
433}
434
435void reader_get_ecm(struct s_reader * reader, ECM_REQUEST *er)
436{
437 struct s_client *cl = reader->client;
438 if(!cl) return;
439 if (er->rc<=E_STOPPED) {
440 //TODO: not sure what this is for, but it was in mpcs too.
441 // ecm request was already answered when the request was started (this ECM_REQUEST is a copy of client->ecmtask[] ECM_REQUEST).
442 // send_dcw is a client function but reader_get_ecm is only called from reader functions where client->ctyp is not set and so send_dcw() will segfault.
443 // so we could use send_dcw(er->client, er) or write_ecm_answer(reader, er), but send_dcw wont be threadsafe from here cause there may be multiple threads accessing same s_client struct.
444 // maybe rc should be checked before request is sent to reader but i could not find the reason why this is happening now and not in v1.10 (zetack)
445 //send_dcw(cl, er);
446 cs_debug_mask(D_TRACE, "skip ecm %04X reader=%s, rc=%d", er->checksum, reader->label, er->rc);
447 return;
448 }
449
450 if (!chk_bcaid(er, &reader->ctab)) {
451 cs_debug_mask(D_READER, "caid %04X filtered", er->caid);
452 write_ecm_answer(reader, er, E_NOTFOUND, E2_CAID, NULL, NULL);
453 return;
454 }
455
456 // cache2
457 struct ecm_request_t *ecm = check_cwcache(er, cl);
458 if (ecm && ecm->rc <= E_NOTFOUND) {
459 cs_debug_mask(D_TRACE, "ecm %04X answer from cache reader=%s", er->checksum, reader->label);
460 write_ecm_answer(reader, er, E_CACHE2, 0, ecm->cw, NULL);
461 return;
462 }
463
464 if (reader->typ & R_IS_CASCADING) {
465 cl->last_srvid=er->srvid;
466 cl->last_caid=er->caid;
467 casc_process_ecm(reader, er);
468 cl->lastecm=time((time_t*)0);
469 return;
470 }
471
472#ifdef WITH_CARDREADER
473
474 if (reader->cooldown[0] && reader->ratelimitecm){
475 if (!reader->cooldowntime)
476 reader->cooldowntime = time((time_t*)0);
477
478 time_t now = time((time_t*)0);
479
480 if (reader->cooldownstate == 1) {
481 if (now - reader->cooldowntime >= reader->cooldown[1]) {
482 reader->cooldownstate = 0;
483 reader->cooldowntime = now;
484 cs_log("%s cooldown OFF", reader->label);
485 }
486 } else {
487 if (now - reader->cooldowntime >= reader->cooldown[0]) {
488 reader->cooldownstate = 1;
489 reader->cooldowntime = now;
490 cs_log("%s cooldown ON", reader->label);
491 }
492 }
493 }
494
495 if ((reader->ratelimitecm && !reader->cooldown[0]) || reader->cooldownstate == 1 ) {
496 cs_debug_mask(D_READER, "ratelimit idx:%d rc:%d caid:%04X srvid:%04X",er->idx,er->rc,er->caid,er->srvid);
497 int32_t foundspace=-1;
498 int32_t h;
499 for (h=0;h<reader->ratelimitecm;h++) {
500 if (reader->rlecmh[h].srvid == er->srvid) {
501 foundspace=h;
502 cs_debug_mask(D_READER, "ratelimit found srvid in use at pos: %d",h);
503 break;
504 }
505 }
506 if (foundspace<0) {
507 for (h=0;h<reader->ratelimitecm;h++) {
508 if ((reader->rlecmh[h].last ==- 1) || ((time(NULL)-reader->rlecmh[h].last) > reader->ratelimitseconds)) {
509 foundspace=h;
510 cs_debug_mask(D_READER, "ratelimit found space at pos: %d old seconds %ld",h,reader->rlecmh[h].last);
511 break;
512 }
513 }
514 }
515 #ifdef HAVE_DVBAPI
516 //overide ratelimit priority for dvbapi request
517 if ((foundspace < 0) && (cfg.dvbapi_enabled == 1) && (strcmp(er->client->account->usr,cfg.dvbapi_usr) == 0)) {
518 if(reader->lastdvbapirateoverride < time(NULL) - reader->ratelimitseconds){
519 time_t minecmtime = time(NULL);
520 for (h=0;h<reader->ratelimitecm;h++) {
521 if(reader->rlecmh[h].last < minecmtime){
522 foundspace = h;
523 minecmtime = reader->rlecmh[h].last;
524 }
525 }
526 reader->lastdvbapirateoverride = time(NULL);
527 cs_debug_mask(D_READER, "Prioritizing DVBAPI User %s over other watching client on reader %s.",er->client->account->usr, reader->label);
528 } else cs_debug_mask(D_READER, "DVBAPI User %s is switching too fast for ratelimit and can't be prioritized on reader %s.",er->client->account->usr, reader->label);
529 }
530 #endif
531
532 if (foundspace<0) {
533 //drop
534 cs_debug_mask(D_READER, "ratelimit could not find space for srvid %04X. Dropping.",er->srvid);
535 write_ecm_answer(reader, er, E_NOTFOUND, E2_RATELIMIT, NULL, "ECMratelimit no space for srvid");
536 return;
537 } else {
538 reader->rlecmh[foundspace].last=time(NULL);
539 reader->rlecmh[foundspace].srvid=er->srvid;
540 }
541 }
542
543 cs_ddump_mask(D_ATR, er->ecm, er->l, "ecm:");
544
545 struct timeb tps, tpe;
546 cs_ftime(&tps);
547
548 struct s_ecm_answer ea;
549 memset(&ea, 0, sizeof(struct s_ecm_answer));
550
551 int32_t rc = reader_ecm(reader, er, &ea);
552
553 ea.rc = E_FOUND; //default assume found
554 ea.rcEx = 0; //no special flag
555
556 if(rc == ERROR ){
557 char buf[32];
558 cs_debug_mask(D_TRACE, "Error processing ecm for caid %04X, srvid %04X (servicename: %s) on reader %s.", er->caid, er->srvid, get_servicename(cl, er->srvid, er->caid, buf), reader->label);
559 ea.rc = E_NOTFOUND;
560 ea.rcEx = 0;
561 if (reader->typ == R_SC8in1 && reader->sc8in1_config->mcr_type) {
562 char text[] = {'S', (char)reader->slot+0x30, 'E', 'e', 'r'};
563 MCR_DisplayText(reader, text, 5, 400, 0);
564 }
565 }
566
567 if(rc == E_CORRUPT ){
568 char buf[32];
569 cs_debug_mask(D_TRACE, "Error processing ecm for caid %04X, srvid %04X (servicename: %s) on reader %s.", er->caid, er->srvid, get_servicename(cl, er->srvid, er->caid, buf), reader->label);
570 ea.rc = E_NOTFOUND;
571 ea.rcEx = E2_WRONG_CHKSUM; //flag it as wrong checksum
572 memcpy (ea.msglog,"Invalid ecm type for card",25);
573 }
574 cs_ftime(&tpe);
575 cl->lastecm=time((time_t*)0);
576
577 cs_debug_mask(D_TRACE, "reader: %s ecm: %04X real time: %ld ms", reader->label, htons(er->checksum), 1000*(tpe.time-tps.time)+tpe.millitm-tps.millitm);
578
579 write_ecm_answer(reader, er, ea.rc, ea.rcEx, ea.cw, ea.msglog);
580 reader_post_process(reader);
581#endif
582}
583
584void reader_log_emm(struct s_reader * reader, EMM_PACKET *ep, int32_t i, int32_t rc, struct timeb *tps) {
585 char *rtxt[] = { "error",
586 (reader->typ & R_IS_CASCADING) ? "sent" : "written", "skipped",
587 "blocked" };
588 char *typedesc[] = { "unknown", "unique", "shared", "global" };
589 struct s_client *cl = reader->client;
590 struct timeb tpe;
591
592 if (reader->logemm & (1 << rc)) {
593 cs_ftime(&tpe);
594 if (!tps)
595 tps = &tpe;
596
597 cs_log("%s emmtype=%s, len=%d, idx=%d, cnt=%d: %s (%ld ms) by %s", username(ep->client), typedesc[cl->emmcache[i].type], ep->emm[2], i, cl->emmcache[i].count, rtxt[rc],
598 1000*(tpe.time-tps->time)+tpe.millitm-tps->millitm, reader->label);
599 }
600
601 if (rc)
602 cl->lastemm = time((time_t*) 0);
603
604#ifdef ARM
605 if (rc && cfg.enableled == 1) cs_switch_led(LED3, LED_BLINK_ON);
606#endif
607
608#if defined(WEBIF) || defined(LCDSUPPORT)
609 //counting results
610 switch (rc) {
611 case 0:
612 reader->emmerror[ep->type]++;
613 break;
614 case 1:
615 reader->emmwritten[ep->type]++;
616 break;
617 case 2:
618 reader->emmskipped[ep->type]++;
619 break;
620 case 3:
621 reader->emmblocked[ep->type]++;
622 break;
623 }
624#endif
625
626#ifdef QBOXHD
627 if (rc && cfg.enableled == 2) qboxhd_led_blink(QBOXHD_LED_COLOR_BLUE,QBOXHD_LED_BLINK_MEDIUM);
628#endif
629}
630
631int32_t reader_do_emm(struct s_reader * reader, EMM_PACKET *ep)
632{
633 int32_t i, rc, ecs;
634 unsigned char md5tmp[MD5_DIGEST_LENGTH];
635 struct timeb tps;
636 struct s_client *cl = reader->client;
637
638 if(!cl) return 0;
639
640 cs_ftime(&tps);
641
642 MD5(ep->emm, ep->emm[2], md5tmp);
643
644 for (i=ecs=0; i<CS_EMMCACHESIZE; i++) {
645 if (!memcmp(cl->emmcache[i].emmd5, md5tmp, CS_EMMSTORESIZE)) {
646 cl->emmcache[i].count++;
647 if (reader->cachemm)
648 ecs=(cl->emmcache[i].count > reader->rewritemm) ? 2 : 1; //skip : rewrite
649 else
650 ecs=1;
651 break;
652 }
653 }
654
655 //Ecs=0 not found in cache
656 //Ecs=1 found in cache, rewrite emm
657 //Ecs=2 skip
658
659 if ((rc=ecs)<2)
660 {
661 if (reader->typ & R_IS_CASCADING) {
662 cs_debug_mask(D_READER, "network emm reader: %s" ,reader->label);
663
664 if (reader->ph.c_send_emm) {
665 rc=reader->ph.c_send_emm(ep);
666 } else {
667 cs_debug_mask(D_READER, "send_emm() support missing");
668 rc=0;
669 }
670 } else {
671 cs_debug_mask(D_READER, "local emm reader: %s" ,reader->label);
672#ifdef WITH_CARDREADER
673 rc=reader_emm(reader, ep);
674#else
675 rc=0;
676#endif
677 }
678
679 if (!ecs)
680 i=reader_store_emm(ep->type, md5tmp);
681 else
682 cl->emmcache[i].count = 0;
683 }
684
685 reader_log_emm(reader, ep, i, rc, &tps);
686
687 return(rc);
688}
689
690void reader_do_card_info(struct s_reader * reader)
691{
692#ifdef WITH_CARDREADER
693 reader_card_info(reader);
694#endif
695 if (reader->ph.c_card_info)
696 reader->ph.c_card_info();
697}
698
699void reader_do_idle(struct s_reader * reader)
700{
701 if (reader->ph.c_idle)
702 reader->ph.c_idle();
703 else {
704 time_t now;
705 int32_t time_diff;
706 time(&now);
707 time_diff = abs(now - reader->last_s);
708 if (time_diff>(reader->tcp_ito*60)) {
709 struct s_client *cl = reader->client;
710 if (cl && reader->tcp_connected && reader->ph.type==MOD_CONN_TCP) {
711 cs_debug_mask(D_READER, "%s inactive_timeout, close connection (fd=%d)", reader->ph.desc, cl->pfd);
712 network_tcp_connection_close(reader, "inactivity");
713 } else
714 reader->last_s = now;
715 }
716 }
717}
718
719int32_t reader_init(struct s_reader *reader) {
720 struct s_client *client = reader->client;
721
722 if (reader->typ & R_IS_CASCADING) {
723 client->typ='p';
724 client->port=reader->r_port;
725 client->ip=cs_inet_addr("0.0.0.0");
726
727 if (!(reader->ph.c_init)) {
728 cs_log("FATAL: %s-protocol not supporting cascading", reader->ph.desc);
729 return 0;
730 }
731
732 if (reader->ph.c_init(client)) {
733 //proxy reader start failed
734 return 0;
735 }
736
737 if ((reader->log_port) && (reader->ph.c_init_log))
738 reader->ph.c_init_log();
739
740 cs_malloc(&client->ecmtask,CS_MAXPENDING*(sizeof(ECM_REQUEST)), 1);
741
742 cs_log("proxy %s initialized (server=%s:%d)", reader->label, reader->device, reader->r_port);
743 }
744#ifdef WITH_CARDREADER
745 else {
746 client->typ='r';
747 client->ip=cs_inet_addr("127.0.0.1");
748 while (reader_device_init(reader)==2){
749 int8_t i = 0;
750 do{
751 cs_sleepms(2000);
752 if(!ll_contains(configured_readers, reader) || !check_client(client) || reader->enable != 1) return 0;
753 ++i;
754 } while (i < 30);
755 }
756 cs_log("reader %s initialized (device=%s, detect=%s%s, mhz=%d, cardmhz=%d)", reader->label, reader->device, reader->detect&0x80 ? "!" : "",RDR_CD_TXT[reader->detect&0x7f], reader->mhz,reader->cardmhz);
757 }
758#endif
759
760 cs_malloc(&client->emmcache,CS_EMMCACHESIZE*(sizeof(struct s_emm)), 1);
761
762 client->login=time((time_t*)0);
763 client->init_done=1;
764
765 return 1;
766}
767
768#if !defined(WITH_CARDREADER) && defined(WITH_STAPI)
769/* Dummy function stub for stapi compiles without cardreader as libstapi needs it. */
770int32_t ATR_InitFromArray (ATR * atr, const BYTE atr_buffer[ATR_MAX_SIZE], uint32_t length){
771 return 0;
772}
773#endif
Note: See TracBrowser for help on using the repository browser.