revert breaks some stupid old compilers
[oscam.git] / module-gbox-cards.c
blob39364f468b39b4f4ec2adfdcaf698b9fefa5a397
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 LLIST *gbox_backup_cards; //NEEDFIX: this list has to be cleaned from time to time
18 CS_MUTEX_LOCK gbox_cards_lock;
19 uchar checkcode[7];
21 GBOX_CARDS_ITER *gbox_cards_iter_create(void)
23 GBOX_CARDS_ITER *gci;
24 if(!cs_malloc(&gci, sizeof(GBOX_CARDS_ITER)))
25 { return NULL; }
26 cs_readlock(__func__, &gbox_cards_lock);
27 gci->it = ll_iter_create(gbox_cards);
28 return gci;
31 void gbox_cards_iter_destroy(GBOX_CARDS_ITER *gci)
33 cs_readunlock(__func__, &gbox_cards_lock);
34 if (gci) { add_garbage(gci); }
37 struct gbox_card *gbox_cards_iter_next(GBOX_CARDS_ITER *gci)
39 if (gci) { return ll_iter_next(&gci->it); }
40 else { return NULL; }
43 void gbox_write_share_cards_info(void)
45 uint16_t card_count_shared = 0;
46 uint16_t card_count_expired = 0;
47 char *fext = FILE_SHARED_CARDS_INFO;
48 char *fname = get_gbox_tmp_fname(fext);
49 FILE *fhandle_shared;
50 fhandle_shared = fopen(fname, "w");
51 if(!fhandle_shared)
53 cs_log("Couldn't open %s: %s", fname, strerror(errno));
54 return;
57 struct gbox_card *card;
58 cs_readlock(__func__, &gbox_cards_lock);
59 LL_ITER it = ll_iter_create(gbox_cards);
60 while((card = ll_iter_next(&it)))
62 if (card->type == GBOX_CARD_TYPE_GBOX)
64 fprintf(fhandle_shared, "CardID %d at %s Card %08X Sl:%d Lev:%1d dist:%1d id:%04X\n",
65 card_count_shared, card->origin_peer->hostname, card->caprovid,
66 card->id.slot, card->lvl, card->dist, card->id.peer);
67 card_count_shared++;
70 cs_readunlock(__func__, &gbox_cards_lock);
71 fclose(fhandle_shared);
73 fext = FILE_BACKUP_CARDS_INFO;
74 fname = get_gbox_tmp_fname(fext);
75 FILE *fhandle_expired;
76 fhandle_expired = fopen(fname, "w");
77 if(!fhandle_expired)
79 cs_log("Couldn't open %s: %s", fname, strerror(errno));
80 return;
82 cs_readlock(__func__, &gbox_cards_lock);
83 LL_ITER it2 = ll_iter_create(gbox_backup_cards);
84 while((card = ll_iter_next(&it2)))
86 if (card->type == GBOX_CARD_TYPE_GBOX)
88 fprintf(fhandle_expired, "CardID %2d at %s Card %08X Sl:%2d Lev:%1d dist:%1d id:%04X\n",
89 card_count_expired, card->origin_peer->hostname, card->caprovid,
90 card->id.slot, card->lvl, card->dist, card->id.peer);
91 card_count_expired++;
94 cs_readunlock(__func__, &gbox_cards_lock);
95 fclose(fhandle_expired);
96 return;
99 void 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;
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);
150 void gbox_write_stats(void)
152 int32_t card_count = 0;
153 struct gbox_good_srvid *srvid_good = NULL;
154 struct gbox_bad_srvid *srvid_bad = NULL;
155 char *fext = FILE_STATS;
156 char *fname = get_gbox_tmp_fname(fext);
157 FILE *fhandle;
158 fhandle = fopen(fname, "w");
159 if(!fhandle)
161 cs_log("Couldn't open %s: %s", fname, strerror(errno));
162 return;
165 struct gbox_card *card;
166 cs_readlock(__func__, &gbox_cards_lock);
167 LL_ITER it = ll_iter_create(gbox_cards);
168 while((card = ll_iter_next(&it)))
170 if (card->type == GBOX_CARD_TYPE_GBOX)
172 fprintf(fhandle, "CardID %4d Card %08X id:%04X #CWs:%d AVGtime:%d ms\n",
173 card_count, card->caprovid, card->id.peer, card->no_cws_returned, card->average_cw_time);
174 fprintf(fhandle, "Good SIDs:\n");
175 LL_ITER it2 = ll_iter_create(card->goodsids);
176 while((srvid_good = ll_iter_next(&it2)))
177 { fprintf(fhandle, "%04X\n", srvid_good->srvid.sid); }
178 fprintf(fhandle, "Bad SIDs:\n");
179 it2 = ll_iter_create(card->badsids);
180 while((srvid_bad = ll_iter_next(&it2)))
181 { fprintf(fhandle, "%04X #%d\n", srvid_bad->srvid.sid, srvid_bad->bad_strikes); }
182 card_count++;
184 } // end of while ll_iter_next
185 cs_readunlock(__func__, &gbox_cards_lock);
187 fclose(fhandle);
188 return;
191 void init_gbox_cards(void)
193 gbox_cards = ll_create("gbox.cards");
194 gbox_backup_cards = ll_create("gbox.backup.cards");
195 cs_lock_create(__func__, &gbox_cards_lock, "gbox_cards_lock", 5000);
196 cs_writelock(__func__, &gbox_cards_lock);
197 checkcode[0] = 0x15;
198 checkcode[1] = 0x30;
199 checkcode[2] = 0x02;
200 checkcode[3] = 0x04;
201 checkcode[4] = 0x19;
202 checkcode[5] = 0x19;
203 checkcode[6] = 0x66;
204 cs_writeunlock(__func__, &gbox_cards_lock);
207 static void update_checkcode(struct gbox_card *card)
209 checkcode[0] ^= (0xFF & (card->caprovid >> 24));
210 checkcode[1] ^= (0xFF & (card->caprovid >> 16));
211 checkcode[2] ^= (0xFF & (card->caprovid >> 8));
212 checkcode[3] ^= (0xFF & (card->caprovid));
213 checkcode[4] ^= (0xFF & (card->id.slot));
214 checkcode[5] ^= (0xFF & (card->id.peer >> 8));
215 checkcode[6] ^= (0xFF & (card->id.peer));
218 static void gbox_free_card(struct gbox_card *card)
220 ll_destroy_data(&card->badsids);
221 ll_destroy_data(&card->goodsids);
222 add_garbage(card);
223 return;
226 static uint8_t closer_path_known(uint32_t caprovid, uint16_t id_peer, uint8_t slot, uint8_t distance)
228 uint8_t ret = 0;
229 struct gbox_card *card;
230 cs_readlock(__func__, &gbox_cards_lock);
231 LL_ITER it = ll_iter_create(gbox_cards);
232 while((card = ll_iter_next(&it)))
234 if (card->caprovid == caprovid && card->id.peer == id_peer && card->id.slot == slot && card->dist <= distance)
236 ret = 1;
237 break;
240 cs_readunlock(__func__, &gbox_cards_lock);
241 return ret;
244 static uint8_t got_from_backup(uint32_t caprovid, uint16_t id_peer, uint8_t slot, struct gbox_peer *origin_peer)
246 uint8_t ret = 0;
247 struct gbox_card *card;
248 cs_writelock(__func__, &gbox_cards_lock);
249 LL_ITER it = ll_iter_create(gbox_backup_cards);
250 while((card = ll_iter_next(&it)))
252 if (card->caprovid == caprovid && card->id.peer == id_peer && card->id.slot == slot)
254 cs_log_dbg(D_READER, "backup card from peer: %04X %08X", card->id.peer, card->caprovid );
255 ll_remove(gbox_backup_cards, card);
256 card->origin_peer = origin_peer;
257 ll_append(gbox_cards, card);
258 update_checkcode(card);
259 ret = 1;
260 break;
263 cs_writeunlock(__func__, &gbox_cards_lock);
264 return ret;
267 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)
269 uint16_t caid = gbox_get_caid(caprovid);
270 uint32_t provid = gbox_get_provid(caprovid);
272 if(!caprovid) //skip caprov 00000000
273 { return; }
274 //don't insert 0100:000000
275 if(caid_is_seca(caid) && (!provid))
276 { return; }
277 //skip CAID 18XX providers
278 if(caid_is_nagra(caid) && (provid))
279 { return; }
281 if (!closer_path_known(caprovid, id_peer, slot, distance) && !got_from_backup(caprovid, id_peer, slot, origin_peer))
283 struct gbox_card *card;
284 if(!cs_malloc(&card, sizeof(struct gbox_card)))
286 cs_log("Card allocation failed");
287 return;
289 cs_log_dbg(D_READER, "new card from peer: %04X %08X", id_peer, caprovid);
290 card->caprovid = caprovid;
291 card->id.peer = id_peer;
292 card->id.slot = slot;
293 card->dist = distance;
294 card->lvl = level;
295 card->badsids = ll_create("badsids");
296 card->goodsids = ll_create("goodsids");
297 card->no_cws_returned = 0;
298 card->average_cw_time = 0;
299 card->type = type;
300 card->origin_peer = origin_peer;
301 cs_writelock(__func__, &gbox_cards_lock);
302 ll_append(gbox_cards, card);
303 update_checkcode(card);
304 cs_writeunlock(__func__, &gbox_cards_lock);
307 return;
310 uchar *gbox_get_my_checkcode(void)
312 return &checkcode[0];
315 uint16_t gbox_count_cards(void)
317 return ll_count(gbox_cards);
320 uint16_t gbox_count_peer_cards(uint16_t peer_id)
322 uint16_t counter = 0;
323 struct gbox_card *card;
325 cs_readlock(__func__, &gbox_cards_lock);
326 LL_ITER it = ll_iter_create(gbox_cards);
327 while((card = ll_iter_next(&it)))
329 if (card->origin_peer && card->origin_peer->gbox.id == peer_id)
330 { counter++; }
332 cs_readunlock(__func__, &gbox_cards_lock);
334 return counter;
337 void gbox_delete_cards(uint8_t delete_type, uint16_t criteria)
339 struct gbox_card *card;
340 uint8_t found;
342 cs_writelock(__func__, &gbox_cards_lock);
343 LL_ITER it = ll_iter_create(gbox_cards);
344 while((card = ll_iter_next(&it)))
346 found = 0;
347 switch (delete_type)
349 case GBOX_DELETE_FROM_PEER:
350 if (card->origin_peer && card->origin_peer->gbox.id == criteria)
351 { found = 1; }
352 break;
353 case GBOX_DELETE_WITH_ID:
354 if (card->id.peer == criteria)
355 { found = 1; }
356 break;
357 case GBOX_DELETE_WITH_TYPE:
358 if (card->type == criteria)
359 { found = 1; }
360 break;
361 default:
362 cs_log("Invalid delete type: %d in gbox_delete_cards", delete_type);
363 break;
365 if (found)
367 cs_log_dbg(D_READER, "remove card from peer: %04X %08X", card->id.peer, card->caprovid);
368 ll_remove(gbox_cards, card);
369 ll_append(gbox_backup_cards, card);
370 update_checkcode(card);
373 cs_writeunlock(__func__, &gbox_cards_lock);
375 return;
378 static void gbox_free_list(LLIST *card_list)
380 if(card_list)
382 cs_writelock(__func__, &gbox_cards_lock);
383 LL_ITER it = ll_iter_create(card_list);
384 struct gbox_card *card;
385 while((card = ll_iter_next_remove(&it)))
386 { gbox_free_card(card); }
387 ll_destroy(&gbox_cards);
388 cs_writeunlock(__func__, &gbox_cards_lock);
390 return;
393 void gbox_free_cardlist(void)
395 gbox_free_list(gbox_cards);
396 gbox_free_list(gbox_backup_cards);
397 return;
400 void gbox_add_good_sid(uint16_t id_card, uint16_t caid, uint8_t slot, uint16_t sid_ok, uint32_t cw_time)
402 struct gbox_card *card = NULL;
403 struct gbox_good_srvid *srvid = NULL;
404 uint8_t factor = 0;
406 cs_writelock(__func__, &gbox_cards_lock);
407 LL_ITER it = ll_iter_create(gbox_cards);
408 while((card = ll_iter_next(&it)))
410 if(card->id.peer == id_card && gbox_get_caid(card->caprovid) == caid && card->id.slot == slot)
412 card->no_cws_returned++;
413 if (!card->no_cws_returned)
414 { card->no_cws_returned = 10; } //wrap around
415 if (card->no_cws_returned < 10)
416 { factor = card->no_cws_returned; }
417 else
418 { factor = 10; }
419 card->average_cw_time = ((card->average_cw_time * (factor-1)) + cw_time) / factor;
420 LL_ITER it2 = ll_iter_create(card->goodsids);
421 while((srvid = ll_iter_next(&it2)))
423 if(srvid->srvid.sid == sid_ok)
425 srvid->last_cw_received = time(NULL);
426 cs_writeunlock(__func__, &gbox_cards_lock);
427 return; // sid_ok is already in the list of goodsids
431 if(!cs_malloc(&srvid, sizeof(struct gbox_good_srvid)))
433 cs_writeunlock(__func__, &gbox_cards_lock);
434 cs_log("Good SID allocation failed");
435 return;
437 srvid->srvid.sid = sid_ok;
438 srvid->srvid.provid_id = gbox_get_provid(card->caprovid);
439 srvid->last_cw_received = time(NULL);
440 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);
441 ll_append(card->goodsids, srvid);
442 break;
444 }//end of ll_iter_next
445 //return dist_c;
446 cs_writeunlock(__func__, &gbox_cards_lock);
447 return;
450 void gbox_remove_bad_sid(uint16_t id_peer, uint8_t id_slot, uint16_t sid)
452 struct gbox_card *card = NULL;
453 struct gbox_bad_srvid *srvid = NULL;
455 cs_writelock(__func__, &gbox_cards_lock);
456 LL_ITER it2 = ll_iter_create(gbox_cards);
457 while((card = ll_iter_next(&it2)))
459 if(card->id.peer == id_peer && card->id.slot == id_slot)
461 LL_ITER it3 = ll_iter_create(card->badsids);
462 while((srvid = ll_iter_next(&it3)))
464 if(srvid->srvid.sid == sid)
466 ll_iter_remove_data(&it3); // remove sid_ok from badsids
467 break;
472 cs_writeunlock(__func__, &gbox_cards_lock);
475 uint8_t gbox_next_free_slot(uint16_t id)
477 struct gbox_card *c;
478 uint8_t lastslot = 0;
480 cs_readlock(__func__, &gbox_cards_lock);
481 LL_ITER it = ll_iter_create(gbox_cards);
482 while((c = ll_iter_next(&it)))
484 if(id == c->id.peer && c->id.slot > lastslot)
485 { lastslot = c->id.slot; }
487 cs_readunlock(__func__, &gbox_cards_lock);
488 return ++lastslot;
491 static int8_t is_already_pending(LLIST *pending_cards, uint16_t peer_id, uint8_t slot)
493 if (!pending_cards)
494 { return -1; }
496 int8_t ret = 0;
497 struct gbox_card_id *current_id;
498 LL_LOCKITER *li = ll_li_create(pending_cards, 0);
499 while ((current_id = ll_li_next(li)))
501 if (current_id->peer == peer_id && current_id->slot == slot)
503 ret = 1;
504 break;
507 ll_li_destroy(li);
508 return ret;
511 uint8_t gbox_get_cards_for_ecm(uchar *send_buf, int32_t len2, uint8_t max_cards, ECM_REQUEST *er, uint32_t *current_avg_card_time, uint16_t peer_id)
513 if (!send_buf || !er)
514 { return 0; }
516 uint8_t nb_matching_crds = 0;
517 struct gbox_good_srvid *srvid_good = NULL;
518 struct gbox_bad_srvid *srvid_bad = NULL;
519 uint8_t enough = 0;
520 uint8_t sid_verified = 0;
521 time_t time_since_lastcw;
523 //loop over good only
524 cs_readlock(__func__, &gbox_cards_lock);
525 LL_ITER it = ll_iter_create(gbox_cards);
526 LL_ITER it2;
527 struct gbox_card *card;
529 while((card = ll_iter_next(&it)))
531 if(card->origin_peer && card->origin_peer->gbox.id == peer_id && card->type == GBOX_CARD_TYPE_GBOX &&
532 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))
534 sid_verified = 0;
536 //check if sid is good
537 it2 = ll_iter_create(card->goodsids);
538 while((srvid_good = ll_iter_next(&it2)))
540 if(srvid_good->srvid.provid_id == er->prid && srvid_good->srvid.sid == er->srvid)
542 if (!enough || *current_avg_card_time > card->average_cw_time)
544 time_since_lastcw = llabs(srvid_good->last_cw_received - time(NULL));
545 *current_avg_card_time = card->average_cw_time;
546 if (enough)
547 { len2 = len2 - 3; }
548 else
550 nb_matching_crds++;
551 if (time_since_lastcw < GBOX_SID_CONFIRM_TIME && er->gbox_ecm_status == GBOX_ECM_NOT_ASKED)
552 { enough = 1; }
554 i2b_buf(2, card->id.peer, send_buf + len2);
555 send_buf[len2 + 2] = card->id.slot;
556 len2 = len2 + 3;
557 sid_verified = 1;
558 break;
563 if(nb_matching_crds == max_cards)
564 { break; }
567 cs_readunlock(__func__, &gbox_cards_lock);
569 //loop over bad and unknown cards
570 cs_writelock(__func__, &gbox_cards_lock);
571 it = ll_iter_create(gbox_cards);
572 while((card = ll_iter_next(&it)))
574 if(card->origin_peer && card->origin_peer->gbox.id == peer_id && card->type == GBOX_CARD_TYPE_GBOX &&
575 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)
577 sid_verified = 0;
579 //check if sid is good
580 it2 = ll_iter_create(card->goodsids);
581 while((srvid_good = ll_iter_next(&it2)))
583 if(srvid_good->srvid.provid_id == er->prid && srvid_good->srvid.sid == er->srvid)
585 sid_verified = 1;
586 cs_log_dbg(D_READER, "ID: %04X SL: %02X SID: %04X is good", card->id.peer, card->id.slot, srvid_good->srvid.sid);
589 if(!sid_verified)
591 //check if sid is bad
592 LL_ITER itt = ll_iter_create(card->badsids);
593 while((srvid_bad = ll_iter_next(&itt)))
595 if(srvid_bad->srvid.provid_id == er->prid && srvid_bad->srvid.sid == er->srvid)
597 if (srvid_bad->bad_strikes < 3)
599 sid_verified = 2;
600 srvid_bad->bad_strikes++;
602 else
603 { sid_verified = 1; }
604 cs_log_dbg(D_READER, "ID: %04X SL: %02X SID: %04X is bad %d", card->id.peer, card->id.slot, srvid_bad->srvid.sid, srvid_bad->bad_strikes);
605 break;
609 //sid is neither good nor bad
610 if(sid_verified != 1)
612 i2b_buf(2, card->id.peer, send_buf + len2);
613 send_buf[len2 + 2] = card->id.slot;
614 len2 = len2 + 3;
615 nb_matching_crds++;
617 if (!sid_verified)
619 if(!cs_malloc(&srvid_bad, sizeof(struct gbox_bad_srvid)))
621 cs_log("ServID allocation failed");
622 cs_writeunlock(__func__, &gbox_cards_lock);
623 return 0;
626 srvid_bad->srvid.sid = er->srvid;
627 srvid_bad->srvid.provid_id = gbox_get_provid(card->caprovid);
628 srvid_bad->bad_strikes = 1;
629 ll_append(card->badsids, srvid_bad);
630 cs_log_dbg(D_READER, "ID: %04X SL: %02X SID: %04X is not checked", card->id.peer, card->id.slot, srvid_bad->srvid.sid);
635 if(nb_matching_crds == max_cards)
636 { break; }
639 cs_writeunlock(__func__, &gbox_cards_lock);
640 return nb_matching_crds;
643 #endif