1 #define MODULE_LOG_PREFIX "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"
17 LLIST
*gbox_backup_cards
; // NEEDFIX: this list has to be cleaned from time to time
18 CS_MUTEX_LOCK gbox_cards_lock
;
21 GBOX_CARDS_ITER
*gbox_cards_iter_create(void)
24 if(!cs_malloc(&gci
, sizeof(GBOX_CARDS_ITER
)))
26 cs_readlock(__func__
, &gbox_cards_lock
);
27 gci
->it
= ll_iter_create(gbox_cards
);
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
); }
43 uint8_t gbox_get_crd_dist_lev(uint16_t crd_id
)
46 uint8_t crd_level
= 0;
47 struct gbox_card
*card
;
48 cs_readlock(__func__
, &gbox_cards_lock
);
49 LL_ITER it
= ll_iter_create(gbox_cards
);
50 while((card
= ll_iter_next(&it
)))
52 if (card
->type
== GBOX_CARD_TYPE_GBOX
&& card
->id
.peer
== crd_id
)
54 crd_dist
= card
->dist
;
55 crd_level
= card
->lvl
;
59 cs_readunlock(__func__
, &gbox_cards_lock
);
60 return ((crd_level
<< 4) | (crd_dist
& 0xf));
63 void gbox_write_share_cards_info(void)
65 uint16_t card_count_shared
= 0;
66 uint16_t card_count_expired
= 0;
67 char *fext
= FILE_SHARED_CARDS_INFO
;
68 char *fname
= get_gbox_tmp_fname(fext
);
70 fhandle_shared
= fopen(fname
, "w");
73 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
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
);
90 cs_readunlock(__func__
, &gbox_cards_lock
);
91 fclose(fhandle_shared
);
93 fext
= FILE_BACKUP_CARDS_INFO
;
94 fname
= get_gbox_tmp_fname(fext
);
95 FILE *fhandle_expired
;
96 fhandle_expired
= fopen(fname
, "w");
99 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
102 cs_readlock(__func__
, &gbox_cards_lock
);
103 LL_ITER it2
= ll_iter_create(gbox_backup_cards
);
104 while((card
= ll_iter_next(&it2
)))
106 if (card
->type
== GBOX_CARD_TYPE_GBOX
)
108 fprintf(fhandle_expired
, "CardID %2d at %s Card %08X Sl:%2d Lev:%1d dist:%1d id:%04X\n",
109 card_count_expired
, card
->origin_peer
->hostname
, card
->caprovid
,
110 card
->id
.slot
, card
->lvl
, card
->dist
, card
->id
.peer
);
111 card_count_expired
++;
114 cs_readunlock(__func__
, &gbox_cards_lock
);
115 fclose(fhandle_expired
);
119 void gbox_write_local_cards_info(void)
121 uint16_t card_count_local
= 0;
122 char *fext
= FILE_LOCAL_CARDS_INFO
;
123 char *fname
= get_gbox_tmp_fname(fext
);
125 fhandle_local
= fopen(fname
, "w");
128 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
132 struct gbox_card
*card
;
133 cs_readlock(__func__
, &gbox_cards_lock
);
134 LL_ITER it
= ll_iter_create(gbox_cards
);
135 while((card
= ll_iter_next(&it
)))
139 case GBOX_CARD_TYPE_GBOX
:
141 case GBOX_CARD_TYPE_LOCAL
:
142 fprintf(fhandle_local
, "CardID:%2d %s %08X Sl:%2d id:%04X\n",
143 card_count_local
, "Local_Card", card
->caprovid
, card
->id
.slot
, card
->id
.peer
);
146 case GBOX_CARD_TYPE_BETUN
:
147 fprintf(fhandle_local
, "CardID:%2d %s %08X Sl:%2d id:%04X\n",
148 card_count_local
, "Betun_Card", card
->caprovid
, card
->id
.slot
, card
->id
.peer
);
151 case GBOX_CARD_TYPE_CCCAM
:
152 fprintf(fhandle_local
, "CardID:%2d %s %08X Sl:%2d id:%04X\n",
153 card_count_local
, "CCcam_Card", card
->caprovid
, card
->id
.slot
, card
->id
.peer
);
156 case GBOX_CARD_TYPE_PROXY
:
157 fprintf(fhandle_local
, "CardID:%2d %s %08X Sl:%2d id:%04X\n",
158 card_count_local
, "Proxy_Card", card
->caprovid
, card
->id
.slot
, card
->id
.peer
);
162 cs_log("Invalid card type: %d in gbox_write_cards_info", card
->type
);
166 cs_readunlock(__func__
, &gbox_cards_lock
);
167 fclose(fhandle_local
);
170 void gbox_write_stats(void)
172 int32_t card_count
= 0;
173 struct gbox_good_srvid
*srvid_good
= NULL
;
174 struct gbox_bad_srvid
*srvid_bad
= NULL
;
175 char *fext
= FILE_STATS
;
176 char *fname
= get_gbox_tmp_fname(fext
);
178 fhandle
= fopen(fname
, "w");
181 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
185 struct gbox_card
*card
;
186 cs_readlock(__func__
, &gbox_cards_lock
);
187 LL_ITER it
= ll_iter_create(gbox_cards
);
188 while((card
= ll_iter_next(&it
)))
190 if (card
->type
== GBOX_CARD_TYPE_GBOX
)
192 fprintf(fhandle
, "CardID %4d Card %08X id:%04X #CWs:%d AVGtime:%d ms\n",
193 card_count
, card
->caprovid
, card
->id
.peer
, card
->no_cws_returned
, card
->average_cw_time
);
194 fprintf(fhandle
, "Good SIDs:\n");
195 LL_ITER it2
= ll_iter_create(card
->goodsids
);
196 while((srvid_good
= ll_iter_next(&it2
)))
197 { fprintf(fhandle
, "%04X\n", srvid_good
->srvid
.sid
); }
198 fprintf(fhandle
, "Bad SIDs:\n");
199 it2
= ll_iter_create(card
->badsids
);
200 while((srvid_bad
= ll_iter_next(&it2
)))
201 { fprintf(fhandle
, "%04X #%d\n", srvid_bad
->srvid
.sid
, srvid_bad
->bad_strikes
); }
204 } // end of while ll_iter_next
205 cs_readunlock(__func__
, &gbox_cards_lock
);
211 void init_gbox_cards(void)
213 gbox_cards
= ll_create("gbox.cards");
214 gbox_backup_cards
= ll_create("gbox.backup.cards");
215 cs_lock_create(__func__
, &gbox_cards_lock
, "gbox_cards_lock", 5000);
216 cs_writelock(__func__
, &gbox_cards_lock
);
224 cs_writeunlock(__func__
, &gbox_cards_lock
);
227 static void update_checkcode(struct gbox_card
*card
)
229 checkcode
[0] ^= (0xFF & (card
->caprovid
>> 24));
230 checkcode
[1] ^= (0xFF & (card
->caprovid
>> 16));
231 checkcode
[2] ^= (0xFF & (card
->caprovid
>> 8));
232 checkcode
[3] ^= (0xFF & (card
->caprovid
));
233 checkcode
[4] ^= (0xFF & (card
->id
.slot
));
234 checkcode
[5] ^= (0xFF & (card
->id
.peer
>> 8));
235 checkcode
[6] ^= (0xFF & (card
->id
.peer
));
238 static void gbox_free_card(struct gbox_card
*card
)
240 ll_destroy_data(&card
->badsids
);
241 ll_destroy_data(&card
->goodsids
);
246 static uint8_t closer_path_known(uint32_t caprovid
, uint16_t id_peer
, uint8_t slot
, uint8_t distance
)
249 struct gbox_card
*card
;
250 cs_readlock(__func__
, &gbox_cards_lock
);
251 LL_ITER it
= ll_iter_create(gbox_cards
);
252 while((card
= ll_iter_next(&it
)))
254 if (card
->caprovid
== caprovid
&& card
->id
.peer
== id_peer
&& card
->id
.slot
== slot
&& card
->dist
<= distance
)
260 cs_readunlock(__func__
, &gbox_cards_lock
);
264 static uint8_t got_from_backup(uint32_t caprovid
, uint16_t id_peer
, uint8_t slot
, struct gbox_peer
*origin_peer
)
267 struct gbox_card
*card
;
268 cs_writelock(__func__
, &gbox_cards_lock
);
269 LL_ITER it
= ll_iter_create(gbox_backup_cards
);
270 while((card
= ll_iter_next(&it
)))
272 if (card
->caprovid
== caprovid
&& card
->id
.peer
== id_peer
&& card
->id
.slot
== slot
)
274 cs_log_dbg(D_READER
, "backup card from peer: %04X %08X", card
->id
.peer
, card
->caprovid
);
275 ll_remove(gbox_backup_cards
, card
);
276 card
->origin_peer
= origin_peer
;
277 ll_append(gbox_cards
, card
);
278 update_checkcode(card
);
283 cs_writeunlock(__func__
, &gbox_cards_lock
);
287 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
)
289 uint16_t caid
= gbox_get_caid(caprovid
);
290 uint32_t provid
= gbox_get_provid(caprovid
);
292 if(!caprovid
) // skip caprov 00000000
294 // don't insert 0100:000000
295 if(caid_is_seca(caid
) && (!provid
))
297 // skip CAID 18XX providers
298 if(caid_is_nagra(caid
) && (provid
))
301 if (!closer_path_known(caprovid
, id_peer
, slot
, distance
) && !got_from_backup(caprovid
, id_peer
, slot
, origin_peer
))
303 struct gbox_card
*card
;
304 if(!cs_malloc(&card
, sizeof(struct gbox_card
)))
306 cs_log("Card allocation failed");
309 cs_log_dbg(D_READER
, "new card from peer: %04X %08X", id_peer
, caprovid
);
310 card
->caprovid
= caprovid
;
311 card
->id
.peer
= id_peer
;
312 card
->id
.slot
= slot
;
313 card
->dist
= distance
;
315 card
->badsids
= ll_create("badsids");
316 card
->goodsids
= ll_create("goodsids");
317 card
->no_cws_returned
= 0;
318 card
->average_cw_time
= 0;
320 card
->origin_peer
= origin_peer
;
321 cs_writelock(__func__
, &gbox_cards_lock
);
322 ll_append(gbox_cards
, card
);
323 update_checkcode(card
);
324 cs_writeunlock(__func__
, &gbox_cards_lock
);
330 uint8_t *gbox_get_my_checkcode(void)
332 return &checkcode
[0];
335 uint16_t gbox_count_cards(void)
337 return ll_count(gbox_cards
);
340 uint16_t gbox_count_peer_cards(uint16_t peer_id
)
342 uint16_t counter
= 0;
343 struct gbox_card
*card
;
345 cs_readlock(__func__
, &gbox_cards_lock
);
346 LL_ITER it
= ll_iter_create(gbox_cards
);
347 while((card
= ll_iter_next(&it
)))
349 if (card
->origin_peer
&& card
->origin_peer
->gbox
.id
== peer_id
)
352 cs_readunlock(__func__
, &gbox_cards_lock
);
357 void gbox_delete_cards(uint8_t delete_type
, uint16_t criteria
)
359 struct gbox_card
*card
;
362 cs_writelock(__func__
, &gbox_cards_lock
);
363 LL_ITER it
= ll_iter_create(gbox_cards
);
364 while((card
= ll_iter_next(&it
)))
369 case GBOX_DELETE_FROM_PEER
:
370 if (card
->origin_peer
&& card
->origin_peer
->gbox
.id
== criteria
)
373 case GBOX_DELETE_WITH_ID
:
374 if (card
->id
.peer
== criteria
)
377 case GBOX_DELETE_WITH_TYPE
:
378 if (card
->type
== criteria
)
382 cs_log("Invalid delete type: %d in gbox_delete_cards", delete_type
);
387 cs_log_dbg(D_READER
, "remove card from peer: %04X %08X", card
->id
.peer
, card
->caprovid
);
388 ll_remove(gbox_cards
, card
);
389 ll_append(gbox_backup_cards
, card
);
390 update_checkcode(card
);
393 cs_writeunlock(__func__
, &gbox_cards_lock
);
398 static void gbox_free_list(LLIST
*card_list
)
402 cs_writelock(__func__
, &gbox_cards_lock
);
403 LL_ITER it
= ll_iter_create(card_list
);
404 struct gbox_card
*card
;
405 while((card
= ll_iter_next_remove(&it
)))
406 { gbox_free_card(card
); }
407 ll_destroy(&gbox_cards
);
408 cs_writeunlock(__func__
, &gbox_cards_lock
);
413 void gbox_free_cardlist(void)
415 gbox_free_list(gbox_cards
);
416 gbox_free_list(gbox_backup_cards
);
420 void gbox_add_good_sid(uint16_t id_card
, uint16_t caid
, uint8_t slot
, uint16_t sid_ok
, uint32_t cw_time
)
422 struct gbox_card
*card
= NULL
;
423 struct gbox_good_srvid
*srvid
= NULL
;
426 cs_writelock(__func__
, &gbox_cards_lock
);
427 LL_ITER it
= ll_iter_create(gbox_cards
);
428 while((card
= ll_iter_next(&it
)))
430 if(card
->id
.peer
== id_card
&& gbox_get_caid(card
->caprovid
) == caid
&& card
->id
.slot
== slot
)
432 card
->no_cws_returned
++;
433 if (!card
->no_cws_returned
)
434 { card
->no_cws_returned
= 10; } // wrap around
435 if (card
->no_cws_returned
< 10)
436 { factor
= card
->no_cws_returned
; }
439 card
->average_cw_time
= ((card
->average_cw_time
* (factor
-1)) + cw_time
) / factor
;
440 LL_ITER it2
= ll_iter_create(card
->goodsids
);
441 while((srvid
= ll_iter_next(&it2
)))
443 if(srvid
->srvid
.sid
== sid_ok
)
445 srvid
->last_cw_received
= time(NULL
);
446 cs_writeunlock(__func__
, &gbox_cards_lock
);
447 return; // sid_ok is already in the list of goodsids
451 if(!cs_malloc(&srvid
, sizeof(struct gbox_good_srvid
)))
453 cs_writeunlock(__func__
, &gbox_cards_lock
);
454 cs_log("Good SID allocation failed");
457 srvid
->srvid
.sid
= sid_ok
;
458 srvid
->srvid
.provid_id
= gbox_get_provid(card
->caprovid
);
459 srvid
->last_cw_received
= time(NULL
);
460 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
);
461 ll_append(card
->goodsids
, srvid
);
464 } // end of ll_iter_next
466 cs_writeunlock(__func__
, &gbox_cards_lock
);
470 void gbox_remove_bad_sid(uint16_t id_peer
, uint8_t id_slot
, uint16_t sid
)
472 struct gbox_card
*card
= NULL
;
473 struct gbox_bad_srvid
*srvid
= NULL
;
475 cs_writelock(__func__
, &gbox_cards_lock
);
476 LL_ITER it2
= ll_iter_create(gbox_cards
);
477 while((card
= ll_iter_next(&it2
)))
479 if(card
->id
.peer
== id_peer
&& card
->id
.slot
== id_slot
)
481 LL_ITER it3
= ll_iter_create(card
->badsids
);
482 while((srvid
= ll_iter_next(&it3
)))
484 if(srvid
->srvid
.sid
== sid
)
486 ll_iter_remove_data(&it3
); // remove sid_ok from badsids
492 cs_writeunlock(__func__
, &gbox_cards_lock
);
495 uint8_t gbox_next_free_slot(uint16_t id
)
498 uint8_t lastslot
= 0;
500 cs_readlock(__func__
, &gbox_cards_lock
);
501 LL_ITER it
= ll_iter_create(gbox_cards
);
502 while((c
= ll_iter_next(&it
)))
504 if(id
== c
->id
.peer
&& c
->id
.slot
> lastslot
)
505 { lastslot
= c
->id
.slot
; }
507 cs_readunlock(__func__
, &gbox_cards_lock
);
511 static int8_t is_already_pending(LLIST
*pending_cards
, uint16_t peer_id
, uint8_t slot
)
517 struct gbox_card_id
*current_id
;
518 LL_LOCKITER
*li
= ll_li_create(pending_cards
, 0);
519 while ((current_id
= ll_li_next(li
)))
521 if (current_id
->peer
== peer_id
&& current_id
->slot
== slot
)
531 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
)
533 if (!send_buf
|| !er
)
536 uint8_t nb_matching_crds
= 0;
537 struct gbox_good_srvid
*srvid_good
= NULL
;
538 struct gbox_bad_srvid
*srvid_bad
= NULL
;
540 uint8_t sid_verified
= 0;
541 time_t time_since_lastcw
;
543 // loop over good only
544 cs_readlock(__func__
, &gbox_cards_lock
);
545 LL_ITER it
= ll_iter_create(gbox_cards
);
547 struct gbox_card
*card
;
549 while((card
= ll_iter_next(&it
)))
551 if(card
->origin_peer
&& card
->origin_peer
->gbox
.id
== peer_id
&& card
->type
== GBOX_CARD_TYPE_GBOX
&&
552 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
))
556 // check if sid is good
557 it2
= ll_iter_create(card
->goodsids
);
558 while((srvid_good
= ll_iter_next(&it2
)))
560 if(srvid_good
->srvid
.provid_id
== er
->prid
&& srvid_good
->srvid
.sid
== er
->srvid
)
562 if (!enough
|| *current_avg_card_time
> card
->average_cw_time
)
564 time_since_lastcw
= llabs(srvid_good
->last_cw_received
- time(NULL
));
565 *current_avg_card_time
= card
->average_cw_time
;
571 if (time_since_lastcw
< GBOX_SID_CONFIRM_TIME
&& er
->gbox_ecm_status
== GBOX_ECM_NOT_ASKED
)
574 i2b_buf(2, card
->id
.peer
, send_buf
+ len2
);
575 send_buf
[len2
+ 2] = card
->id
.slot
;
583 if(nb_matching_crds
== max_cards
)
587 cs_readunlock(__func__
, &gbox_cards_lock
);
589 // loop over bad and unknown cards
590 cs_writelock(__func__
, &gbox_cards_lock
);
591 it
= ll_iter_create(gbox_cards
);
592 while((card
= ll_iter_next(&it
)))
594 if(card
->origin_peer
&& card
->origin_peer
->gbox
.id
== peer_id
&& card
->type
== GBOX_CARD_TYPE_GBOX
&&
595 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
)
599 // check if sid is good
600 it2
= ll_iter_create(card
->goodsids
);
601 while((srvid_good
= ll_iter_next(&it2
)))
603 if(srvid_good
->srvid
.provid_id
== er
->prid
&& srvid_good
->srvid
.sid
== er
->srvid
)
606 cs_log_dbg(D_READER
, "ID: %04X SL: %02X SID: %04X is good", card
->id
.peer
, card
->id
.slot
, srvid_good
->srvid
.sid
);
611 // check if sid is bad
612 LL_ITER itt
= ll_iter_create(card
->badsids
);
613 while((srvid_bad
= ll_iter_next(&itt
)))
615 if(srvid_bad
->srvid
.provid_id
== er
->prid
&& srvid_bad
->srvid
.sid
== er
->srvid
)
617 if (srvid_bad
->bad_strikes
< 3)
622 srvid_bad
->bad_strikes
++;
626 srvid_bad
->bad_strikes
= 1;
627 //cs_log("cards.c - get card for ecm - Block bad SID: %04X - %d bad strikes", srvid_bad->srvid.sid, srvid_bad->bad_strikes);
631 { sid_verified
= 1; }
632 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
);
637 // sid is neither good nor bad
638 if(sid_verified
!= 1)
640 i2b_buf(2, card
->id
.peer
, send_buf
+ len2
);
641 send_buf
[len2
+ 2] = card
->id
.slot
;
647 if(!cs_malloc(&srvid_bad
, sizeof(struct gbox_bad_srvid
)))
649 cs_log("ServID allocation failed");
650 cs_writeunlock(__func__
, &gbox_cards_lock
);
654 srvid_bad
->srvid
.sid
= er
->srvid
;
655 srvid_bad
->srvid
.provid_id
= gbox_get_provid(card
->caprovid
);
656 srvid_bad
->bad_strikes
= 1;
657 ll_append(card
->badsids
, srvid_bad
);
658 cs_log_dbg(D_READER
, "ID: %04X SL: %02X SID: %04X is not checked", card
->id
.peer
, card
->id
.slot
, srvid_bad
->srvid
.sid
);
663 if(nb_matching_crds
== max_cards
)
667 cs_writeunlock(__func__
, &gbox_cards_lock
);
668 return nb_matching_crds
;