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 CS_MUTEX_LOCK gbox_cards_lock
;
19 uint8_t last_checkcode
[7];
20 uint8_t sid_verified
= 0;
22 GBOX_CARDS_ITER
*gbox_cards_iter_create(void)
25 if(!cs_malloc(&gci
, sizeof(GBOX_CARDS_ITER
)))
27 cs_readlock(__func__
, &gbox_cards_lock
);
28 gci
->it
= ll_iter_create(gbox_cards
);
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
); }
44 uint8_t gbox_get_crd_dist_lev(uint16_t crd_id
)
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
;
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
);
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
);
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");
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
);
105 fhandle_local
= fopen(fname
, "w");
108 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
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
)))
119 case GBOX_CARD_TYPE_GBOX
:
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
);
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
);
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
);
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
);
142 cs_log("Invalid card type: %d in gbox_write_cards_info", card
->type
);
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
);
161 fhandle
= fopen(fname
, "w");
164 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
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
); }
187 } // end of while ll_iter_next
188 cs_readunlock(__func__
, &gbox_cards_lock
);
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
);
208 uint8_t *gbox_get_my_checkcode(void)
210 return &checkcode
[0];
213 uint8_t *gbox_update_my_checkcode(void)
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
)))
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
)
267 cs_readunlock(__func__
, &gbox_cards_lock
);
272 void gbox_delete_cards(uint8_t delete_type
, uint16_t criteria
)
274 struct gbox_card
*card
;
277 cs_writelock(__func__
, &gbox_cards_lock
);
278 LL_ITER it
= ll_iter_create(gbox_cards
);
279 while((card
= ll_iter_next(&it
)))
284 case GBOX_DELETE_FROM_PEER
:
285 if (card
->origin_peer
&& card
->origin_peer
->gbox
.id
== criteria
)
288 case GBOX_DELETE_WITH_ID
:
289 if (card
->id
.peer
== criteria
)
292 case GBOX_DELETE_WITH_TYPE
:
293 if (card
->type
== criteria
)
297 cs_log("Invalid delete type: %d in gbox_delete_cards", delete_type
);
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
);
309 static uint8_t check_card_properties(uint32_t caprovid
, uint16_t id_peer
, uint8_t slot
, uint8_t distance
, uint8_t type
)
313 if (!distance
) //local card
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
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
350 cs_writeunlock(__func__
, &gbox_cards_lock
);
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
361 //don't insert 0100:000000
362 if(caid_is_seca(caid
) && (!provid
))
364 //skip CAID 18XX providers
365 // if(caid_is_nagra(caid) && (provid))
368 struct gbox_card
*card
;
369 if(!cs_malloc(&card
, sizeof(struct gbox_card
)))
371 cs_log("Card allocation failed");
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
;
382 card
->badsids
= ll_create("badsids");
383 card
->goodsids
= ll_create("goodsids");
384 card
->no_cws_returned
= 0;
385 card
->average_cw_time
= 0;
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
);
395 static void gbox_free_list(LLIST
*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
);
410 void gbox_free_cardlist(void)
412 gbox_free_list(gbox_cards
);
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
;
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
; }
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");
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
);
460 } // end of ll_iter_next
462 cs_writeunlock(__func__
, &gbox_cards_lock
);
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
488 cs_writeunlock(__func__
, &gbox_cards_lock
);
491 uint8_t gbox_next_free_slot(uint16_t id
)
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
);
507 static int8_t is_already_pending(LLIST
*pending_cards
, uint16_t peer_id
, uint8_t slot
)
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
)
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
)
532 uint8_t nb_matching_crds
= 0;
533 struct gbox_good_srvid
*srvid_good
= NULL
;
534 struct gbox_bad_srvid
*srvid_bad
= NULL
;
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
);
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
))
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
;
566 if (time_since_lastcw
< GBOX_SID_CONFIRM_TIME
&& er
->gbox_ecm_status
== GBOX_ECM_NEW_REQ
)
569 i2b_buf(2, card
->id
.peer
, send_buf
+ len2
);
570 send_buf
[len2
+ 2] = card
->id
.slot
;
578 if(nb_matching_crds
== max_cards
)
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
)
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
)
601 cs_log_dbg(D_READER
, "ID: %04X SL: %02X SID: %04X is good", card
->id
.peer
, card
->id
.slot
, srvid_good
->srvid
.sid
);
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)
617 srvid_bad
->bad_strikes
++;
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);
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
);
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
;
642 if(!cs_malloc(&srvid_bad
, sizeof(struct gbox_bad_srvid
)))
644 cs_log("ServID allocation failed");
645 cs_writeunlock(__func__
, &gbox_cards_lock
);
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
)
662 cs_writeunlock(__func__
, &gbox_cards_lock
);
663 return nb_matching_crds
;