- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / module-gbox-cards.c
blobea482fae2835ba1e81cc080fb2d21a5ba5b3d36b
1 #define MODULE_LOG_PREFIX "gbox"
3 #include "globals.h"
5 #ifdef MODULE_GBOX
6 #include "module-gbox.h"
7 #include "module-gbox-cards.h"
8 #include "module-gbox-helper.h"
9 #include "oscam-lock.h"
10 #include "oscam-garbage.h"
11 #include "oscam-files.h"
12 #include "oscam-chk.h"
13 #include "oscam-string.h"
14 #include "oscam-time.h"
16 LLIST *gbox_cards;
17 CS_MUTEX_LOCK gbox_cards_lock;
18 uint8_t checkcode[7];
19 uint8_t last_checkcode[7];
20 uint8_t sid_verified = 0;
22 GBOX_CARDS_ITER *gbox_cards_iter_create(void)
24 GBOX_CARDS_ITER *gci;
25 if(!cs_malloc(&gci, sizeof(GBOX_CARDS_ITER)))
26 { return NULL; }
27 cs_readlock(__func__, &gbox_cards_lock);
28 gci->it = ll_iter_create(gbox_cards);
29 return gci;
32 void gbox_cards_iter_destroy(GBOX_CARDS_ITER *gci)
34 cs_readunlock(__func__, &gbox_cards_lock);
35 if (gci) { add_garbage(gci); }
38 struct gbox_card *gbox_cards_iter_next(GBOX_CARDS_ITER *gci)
40 if (gci) { return ll_iter_next(&gci->it); }
41 else { return NULL; }
44 uint8_t gbox_get_crd_dist_lev(uint16_t crd_id)
46 uint8_t crd_dist = 0;
47 uint8_t crd_level = 0;
48 struct gbox_card *card;
49 cs_readlock(__func__, &gbox_cards_lock);
50 LL_ITER it = ll_iter_create(gbox_cards);
51 while((card = ll_iter_next(&it)))
53 if ((card->type == GBOX_CARD_TYPE_GBOX || card->type == GBOX_CARD_TYPE_CCCAM) && card->id.peer == crd_id)
55 crd_dist = card->dist;
56 crd_level = card->lvl;
57 break;
60 cs_readunlock(__func__, &gbox_cards_lock);
61 return ((crd_level << 4) | (crd_dist & 0xf));
64 void gbox_write_share_cards_info(void)
66 uint16_t card_count_shared = 0;
67 char *fext = FILE_SHARED_CARDS_INFO;
68 char *fname = get_gbox_tmp_fname(fext);
69 FILE *fhandle_shared;
70 fhandle_shared = fopen(fname, "w");
71 if(!fhandle_shared)
73 cs_log("Couldn't open %s: %s", fname, strerror(errno));
74 return;
77 struct gbox_card *card;
78 cs_readlock(__func__, &gbox_cards_lock);
79 LL_ITER it = ll_iter_create(gbox_cards);
80 while((card = ll_iter_next(&it)))
82 if (card->type == GBOX_CARD_TYPE_GBOX)
84 fprintf(fhandle_shared, "CardID %d at %s Card %08X Sl:%d Lev:%1d dist:%1d id:%04X\n",
85 card_count_shared, card->origin_peer->hostname, card->caprovid,
86 card->id.slot, card->lvl, card->dist, card->id.peer);
87 card_count_shared++;
90 cs_readunlock(__func__, &gbox_cards_lock);
91 //char tmp[32];
92 //fprintf(fhandle_shared, "my checkcode: %s",cs_hexdump(1, gbox_get_my_checkcode(), 7, tmp, sizeof(tmp)));
93 fclose(fhandle_shared);
94 cs_log_dbg(D_READER,"share.info written");
95 //cs_log("share.info written");
96 return;
99 uint16_t gbox_write_local_cards_info(void)
101 uint16_t card_count_local = 0;
102 char *fext = FILE_LOCAL_CARDS_INFO;
103 char *fname = get_gbox_tmp_fname(fext);
104 FILE *fhandle_local;
105 fhandle_local = fopen(fname, "w");
106 if(!fhandle_local)
108 cs_log("Couldn't open %s: %s", fname, strerror(errno));
109 return 0;
112 struct gbox_card *card;
113 cs_readlock(__func__, &gbox_cards_lock);
114 LL_ITER it = ll_iter_create(gbox_cards);
115 while((card = ll_iter_next(&it)))
117 switch (card->type)
119 case GBOX_CARD_TYPE_GBOX:
120 break;
121 case GBOX_CARD_TYPE_LOCAL:
122 fprintf(fhandle_local, "CardID:%2d %s %08X Sl:%2d id:%04X\n",
123 card_count_local, "Local_Card", card->caprovid, card->id.slot, card->id.peer);
124 card_count_local++;
125 break;
126 case GBOX_CARD_TYPE_BETUN:
127 fprintf(fhandle_local, "CardID:%2d %s %08X Sl:%2d id:%04X\n",
128 card_count_local, "Betun_Card", card->caprovid, card->id.slot, card->id.peer);
129 card_count_local++;
130 break;
131 case GBOX_CARD_TYPE_CCCAM:
132 fprintf(fhandle_local, "CardID:%2d %s %08X Sl:%2d id:%04X\n",
133 card_count_local, "CCcam_Card", card->caprovid, card->id.slot, card->id.peer);
134 card_count_local++;
135 break;
136 case GBOX_CARD_TYPE_PROXY:
137 fprintf(fhandle_local, "CardID:%2d %s %08X Sl:%2d id:%04X\n",
138 card_count_local, "Proxy_Card", card->caprovid, card->id.slot, card->id.peer);
139 card_count_local++;
140 break;
141 default:
142 cs_log("Invalid card type: %d in gbox_write_cards_info", card->type);
143 break;
146 cs_readunlock(__func__, &gbox_cards_lock);
147 fclose(fhandle_local);
148 cs_log_dbg(D_READER,"sc.info written");
149 //cs_log("sc.info written");
150 return card_count_local;
153 void gbox_write_stats(void)
155 int32_t card_count = 0;
156 struct gbox_good_srvid *srvid_good = NULL;
157 struct gbox_bad_srvid *srvid_bad = NULL;
158 char *fext = FILE_STATS;
159 char *fname = get_gbox_tmp_fname(fext);
160 FILE *fhandle;
161 fhandle = fopen(fname, "w");
162 if(!fhandle)
164 cs_log("Couldn't open %s: %s", fname, strerror(errno));
165 return;
167 fprintf(fhandle, "Statistics for peer cards received\n");
168 struct gbox_card *card;
169 cs_readlock(__func__, &gbox_cards_lock);
170 LL_ITER it = ll_iter_create(gbox_cards);
171 while((card = ll_iter_next(&it)))
173 if (card->type == GBOX_CARD_TYPE_GBOX)
175 fprintf(fhandle, "\nCard# %04d CaProv:%08X ID:%04X #CWs:%d AVGtime:%d ms",
176 card_count +1, card->caprovid, card->id.peer, card->no_cws_returned, card->average_cw_time);
177 fprintf(fhandle, "\n Good SID: ");
178 LL_ITER it2 = ll_iter_create(card->goodsids);
179 while((srvid_good = ll_iter_next(&it2)))
180 { fprintf(fhandle, "%04X ", srvid_good->srvid.sid); }
181 fprintf(fhandle, "\n Bad SID: ");
182 it2 = ll_iter_create(card->badsids);
183 while((srvid_bad = ll_iter_next(&it2)))
184 { fprintf(fhandle, "%04X ", srvid_bad->srvid.sid); }
185 card_count++;
187 } // end of while ll_iter_next
188 cs_readunlock(__func__, &gbox_cards_lock);
190 fclose(fhandle);
191 return;
194 void init_gbox_cards_list(void)
196 gbox_cards = ll_create("gbox.cards");
197 cs_lock_create(__func__, &gbox_cards_lock, "gbox_cards_lock", 5000);
200 static void gbox_free_card(struct gbox_card *card)
202 ll_destroy_data(&card->badsids);
203 ll_destroy_data(&card->goodsids);
204 add_garbage(card);
205 return;
208 uint8_t *gbox_get_my_checkcode(void)
210 return &checkcode[0];
213 uint8_t *gbox_update_my_checkcode(void)
215 checkcode[0] = 0x15;
216 checkcode[1] = 0x30;
217 checkcode[2] = 0x02;
218 checkcode[3] = 0x04;
219 checkcode[4] = 0x19;
220 checkcode[5] = 0x19;
221 checkcode[6] = 0x66;
223 struct gbox_card *card;
224 cs_readlock(__func__, &gbox_cards_lock);
225 LL_ITER it = ll_iter_create(gbox_cards);
226 while((card = ll_iter_next(&it)))
228 if(card->lvl)
230 checkcode[0] ^= (0xFF & (card->caprovid >> 24));
231 checkcode[1] ^= (0xFF & (card->caprovid >> 16));
232 checkcode[2] ^= (0xFF & (card->caprovid >> 8));
233 checkcode[3] ^= (0xFF & (card->caprovid));
234 checkcode[4] ^= (0xFF & (card->id.slot));
235 checkcode[5] ^= (0xFF & (card->id.peer >> 8));
236 checkcode[6] ^= (0xFF & (card->id.peer));
239 cs_readunlock(__func__, &gbox_cards_lock);
241 if(memcmp(last_checkcode, checkcode, 7))
243 memcpy(last_checkcode, checkcode, 7);
244 //cs_log_dump(gbox_get_my_checkcode(), 7, "my checkcode updated:");
245 cs_log_dump_dbg(D_READER, gbox_get_my_checkcode(), 7, "my checkcode updated:");
247 return &checkcode[0];
250 uint16_t gbox_count_cards(void)
252 return ll_count(gbox_cards);
255 uint16_t gbox_count_peer_cards(uint16_t peer_id)
257 uint16_t counter = 0;
258 struct gbox_card *card;
260 cs_readlock(__func__, &gbox_cards_lock);
261 LL_ITER it = ll_iter_create(gbox_cards);
262 while((card = ll_iter_next(&it)))
264 if (card->origin_peer && card->origin_peer->gbox.id == peer_id)
265 { counter++; }
267 cs_readunlock(__func__, &gbox_cards_lock);
269 return counter;
272 void gbox_delete_cards(uint8_t delete_type, uint16_t criteria)
274 struct gbox_card *card;
275 uint8_t found;
277 cs_writelock(__func__, &gbox_cards_lock);
278 LL_ITER it = ll_iter_create(gbox_cards);
279 while((card = ll_iter_next(&it)))
281 found = 0;
282 switch (delete_type)
284 case GBOX_DELETE_FROM_PEER:
285 if (card->origin_peer && card->origin_peer->gbox.id == criteria)
286 { found = 1; }
287 break;
288 case GBOX_DELETE_WITH_ID:
289 if (card->id.peer == criteria)
290 { found = 1; }
291 break;
292 case GBOX_DELETE_WITH_TYPE:
293 if (card->type == criteria)
294 { found = 1; }
295 break;
296 default:
297 cs_log("Invalid delete type: %d in gbox_delete_cards", delete_type);
298 break;
300 if (found)
302 cs_log_dbg(D_READER, "remove card from card_list - peer: %04X %08X dist %d", card->id.peer, card->caprovid, card->dist);
303 ll_remove(gbox_cards, card);
306 cs_writeunlock(__func__, &gbox_cards_lock);
307 return;
309 static uint8_t check_card_properties(uint32_t caprovid, uint16_t id_peer, uint8_t slot, uint8_t distance, uint8_t type)
311 uint8_t ret = 1;
313 if (!distance) //local card
314 { return ret; }
316 struct gbox_card *card;
317 cs_writelock(__func__, &gbox_cards_lock);
318 LL_ITER it = ll_iter_create(gbox_cards);
319 while((card = ll_iter_next(&it)))
321 if (card->caprovid == caprovid && card->id.peer == id_peer && card->id.slot == slot && type != GBOX_CARD_TYPE_CCCAM)
323 if (distance < card->dist) //better card
325 ll_remove(gbox_cards, card);
326 ret = 1; //let card pass
327 break;
329 else
331 ret = 0; //skip card
332 break;
335 if (card->caprovid == caprovid && card->id.peer == id_peer && type == GBOX_CARD_TYPE_CCCAM)
337 if (distance < card->dist) //better card
339 ll_remove(gbox_cards, card);
340 ret = 1; //let card pass
341 break;
343 else
345 ret = 0; //skip card
346 break;
350 cs_writeunlock(__func__, &gbox_cards_lock);
351 return ret;
354 void gbox_add_card(uint16_t id_peer, uint32_t caprovid, uint8_t slot, uint8_t level, uint8_t distance, uint8_t type, struct gbox_peer *origin_peer)
356 uint16_t caid = gbox_get_caid(caprovid);
357 uint32_t provid = gbox_get_provid(caprovid);
359 if(!caprovid) //skip caprov 00000000
360 { return; }
361 //don't insert 0100:000000
362 if(caid_is_seca(caid) && (!provid))
363 { return; }
364 //skip CAID 18XX providers
365 // if(caid_is_nagra(caid) && (provid))
366 // { return; }
368 struct gbox_card *card;
369 if(!cs_malloc(&card, sizeof(struct gbox_card)))
371 cs_log("Card allocation failed");
372 return;
374 if (check_card_properties(caprovid, id_peer, slot, distance, type) && !check_peer_ignored(id_peer))
376 cs_log_dbg(D_READER, "add card to card_list - peer: %04X %08X dist %d", id_peer, caprovid, distance);
377 card->caprovid = caprovid;
378 card->id.peer = id_peer;
379 card->id.slot = slot;
380 card->dist = distance;
381 card->lvl = level;
382 card->badsids = ll_create("badsids");
383 card->goodsids = ll_create("goodsids");
384 card->no_cws_returned = 0;
385 card->average_cw_time = 0;
386 card->type = type;
387 card->origin_peer = origin_peer;
388 cs_writelock(__func__, &gbox_cards_lock);
389 ll_append(gbox_cards, card);
390 cs_writeunlock(__func__, &gbox_cards_lock);
392 return;
395 static void gbox_free_list(LLIST *card_list)
397 if(card_list)
399 cs_writelock(__func__, &gbox_cards_lock);
400 LL_ITER it = ll_iter_create(card_list);
401 struct gbox_card *card;
402 while((card = ll_iter_next_remove(&it)))
403 { gbox_free_card(card); }
404 ll_destroy(&gbox_cards);
405 cs_writeunlock(__func__, &gbox_cards_lock);
407 return;
410 void gbox_free_cardlist(void)
412 gbox_free_list(gbox_cards);
413 return;
416 void gbox_add_good_sid(uint16_t id_card, uint16_t caid, uint8_t slot, uint16_t sid_ok, uint32_t cw_time)
418 struct gbox_card *card = NULL;
419 struct gbox_good_srvid *srvid = NULL;
420 uint8_t factor = 0;
422 cs_writelock(__func__, &gbox_cards_lock);
423 LL_ITER it = ll_iter_create(gbox_cards);
424 while((card = ll_iter_next(&it)))
426 if(card->id.peer == id_card && gbox_get_caid(card->caprovid) == caid && card->id.slot == slot)
428 card->no_cws_returned++;
429 if (!card->no_cws_returned)
430 { card->no_cws_returned = 10; } // wrap around
431 if (card->no_cws_returned < 10)
432 { factor = card->no_cws_returned; }
433 else
434 { factor = 10; }
435 card->average_cw_time = ((card->average_cw_time * (factor-1)) + cw_time) / factor;
436 LL_ITER it2 = ll_iter_create(card->goodsids);
437 while((srvid = ll_iter_next(&it2)))
439 if(srvid->srvid.sid == sid_ok)
441 srvid->last_cw_received = time(NULL);
442 cs_writeunlock(__func__, &gbox_cards_lock);
443 return; // sid_ok is already in the list of goodsids
447 if(!cs_malloc(&srvid, sizeof(struct gbox_good_srvid)))
449 cs_writeunlock(__func__, &gbox_cards_lock);
450 cs_log("Good SID allocation failed");
451 return;
453 srvid->srvid.sid = sid_ok;
454 srvid->srvid.provid_id = gbox_get_provid(card->caprovid);
455 srvid->last_cw_received = time(NULL);
456 cs_log_dbg(D_READER, "Adding good SID: %04X for CAID: %04X Provider: %04X on CardID: %04X", sid_ok, caid, gbox_get_provid(card->caprovid), id_card);
457 ll_append(card->goodsids, srvid);
458 break;
460 } // end of ll_iter_next
461 // return dist_c;
462 cs_writeunlock(__func__, &gbox_cards_lock);
463 return;
466 void gbox_remove_bad_sid(uint16_t id_peer, uint8_t id_slot, uint16_t sid)
468 struct gbox_card *card = NULL;
469 struct gbox_bad_srvid *srvid = NULL;
471 cs_writelock(__func__, &gbox_cards_lock);
472 LL_ITER it2 = ll_iter_create(gbox_cards);
473 while((card = ll_iter_next(&it2)))
475 if(card->id.peer == id_peer && card->id.slot == id_slot)
477 LL_ITER it3 = ll_iter_create(card->badsids);
478 while((srvid = ll_iter_next(&it3)))
480 if(srvid->srvid.sid == sid)
482 ll_iter_remove_data(&it3); // remove sid_ok from badsids
483 break;
488 cs_writeunlock(__func__, &gbox_cards_lock);
491 uint8_t gbox_next_free_slot(uint16_t id)
493 struct gbox_card *c;
494 uint8_t lastslot = 0;
496 cs_readlock(__func__, &gbox_cards_lock);
497 LL_ITER it = ll_iter_create(gbox_cards);
498 while((c = ll_iter_next(&it)))
500 if(id == c->id.peer && c->id.slot > lastslot)
501 { lastslot = c->id.slot; }
503 cs_readunlock(__func__, &gbox_cards_lock);
504 return ++lastslot;
507 static int8_t is_already_pending(LLIST *pending_cards, uint16_t peer_id, uint8_t slot)
509 if (!pending_cards)
510 { return -1; }
512 int8_t ret = 0;
513 struct gbox_card_id *current_id;
514 LL_LOCKITER *li = ll_li_create(pending_cards, 0);
515 while ((current_id = ll_li_next(li)))
517 if (current_id->peer == peer_id && current_id->slot == slot)
519 ret = 1;
520 break;
523 ll_li_destroy(li);
524 return ret;
527 uint8_t gbox_get_cards_for_ecm(uint8_t *send_buf, int32_t len2, uint8_t max_cards, ECM_REQUEST *er, uint32_t *current_avg_card_time, uint16_t peer_id, uint8_t force_remm)
529 if (!send_buf || !er)
530 { return 0; }
532 uint8_t nb_matching_crds = 0;
533 struct gbox_good_srvid *srvid_good = NULL;
534 struct gbox_bad_srvid *srvid_bad = NULL;
535 uint8_t enough = 0;
536 time_t time_since_lastcw;
538 // loop over good only
539 cs_readlock(__func__, &gbox_cards_lock);
540 LL_ITER it = ll_iter_create(gbox_cards);
541 LL_ITER it2;
542 struct gbox_card *card;
544 while((card = ll_iter_next(&it)))
546 if(card->origin_peer && card->origin_peer->gbox.id == peer_id && card->type == GBOX_CARD_TYPE_GBOX &&
547 gbox_get_caid(card->caprovid) == er->caid && gbox_get_provid(card->caprovid) == er->prid && !is_already_pending(er->gbox_cards_pending, card->id.peer, card->id.slot))
549 sid_verified = 0;
551 // check if sid is good
552 it2 = ll_iter_create(card->goodsids);
553 while((srvid_good = ll_iter_next(&it2)))
555 if(srvid_good->srvid.provid_id == er->prid && srvid_good->srvid.sid == er->srvid)
557 if (!enough || *current_avg_card_time > card->average_cw_time)
559 time_since_lastcw = llabs(srvid_good->last_cw_received - time(NULL));
560 *current_avg_card_time = card->average_cw_time;
561 if (enough)
562 { len2 = len2 - 3; }
563 else
565 nb_matching_crds++;
566 if (time_since_lastcw < GBOX_SID_CONFIRM_TIME && er->gbox_ecm_status == GBOX_ECM_NEW_REQ)
567 { enough = 1; }
569 i2b_buf(2, card->id.peer, send_buf + len2);
570 send_buf[len2 + 2] = card->id.slot;
571 len2 = len2 + 3;
572 sid_verified = 1;
573 break;
578 if(nb_matching_crds == max_cards)
579 { break; }
582 cs_readunlock(__func__, &gbox_cards_lock);
584 // loop over bad and unknown cards
585 cs_writelock(__func__, &gbox_cards_lock);
586 it = ll_iter_create(gbox_cards);
587 while((card = ll_iter_next(&it)))
589 if(card->origin_peer && card->origin_peer->gbox.id == peer_id && card->type == GBOX_CARD_TYPE_GBOX &&
590 gbox_get_caid(card->caprovid) == er->caid && gbox_get_provid(card->caprovid) == er->prid && !is_already_pending(er->gbox_cards_pending, card->id.peer, card->id.slot) && !enough)
592 sid_verified = 0;
594 // check if sid is good
595 it2 = ll_iter_create(card->goodsids);
596 while((srvid_good = ll_iter_next(&it2)))
598 if(srvid_good->srvid.provid_id == er->prid && srvid_good->srvid.sid == er->srvid)
600 sid_verified = 1;
601 cs_log_dbg(D_READER, "ID: %04X SL: %02X SID: %04X is good", card->id.peer, card->id.slot, srvid_good->srvid.sid);
604 if(!sid_verified)
606 // check if sid is bad
607 LL_ITER itt = ll_iter_create(card->badsids);
608 while((srvid_bad = ll_iter_next(&itt)))
610 if(srvid_bad->srvid.provid_id == er->prid && srvid_bad->srvid.sid == er->srvid)
612 if (srvid_bad->bad_strikes < 3)
614 sid_verified = 2;
615 if(!force_remm)
617 srvid_bad->bad_strikes++;
619 else
621 srvid_bad->bad_strikes = 1;
622 //cs_log("cards.c - get card for ecm - Block bad SID: %04X - %d bad strikes", srvid_bad->srvid.sid, srvid_bad->bad_strikes);
625 else
626 { sid_verified = 1; }
627 cs_log_dbg(D_READER, "CRD_ID: %04X Slot: %d SID: %04X failed to relpy %d times", card->id.peer, card->id.slot, srvid_bad->srvid.sid, srvid_bad->bad_strikes);
628 break;
632 // sid is neither good nor bad
633 if(sid_verified != 1)
635 i2b_buf(2, card->id.peer, send_buf + len2);
636 send_buf[len2 + 2] = card->id.slot;
637 len2 = len2 + 3;
638 nb_matching_crds++;
640 if (!sid_verified)
642 if(!cs_malloc(&srvid_bad, sizeof(struct gbox_bad_srvid)))
644 cs_log("ServID allocation failed");
645 cs_writeunlock(__func__, &gbox_cards_lock);
646 return 0;
649 srvid_bad->srvid.sid = er->srvid;
650 srvid_bad->srvid.provid_id = gbox_get_provid(card->caprovid);
651 srvid_bad->bad_strikes = 1;
652 ll_append(card->badsids, srvid_bad);
653 cs_log_dbg(D_READER, "ID: %04X SL: %02X SID: %04X is not checked", card->id.peer, card->id.slot, srvid_bad->srvid.sid);
658 if(nb_matching_crds == max_cards)
659 { break; }
662 cs_writeunlock(__func__, &gbox_cards_lock);
663 return nb_matching_crds;
666 #endif