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 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
);
50 fhandle_shared
= fopen(fname
, "w");
53 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
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
);
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");
79 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
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
);
94 cs_readunlock(__func__
, &gbox_cards_lock
);
95 fclose(fhandle_expired
);
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
);
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
);
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
);
158 fhandle
= fopen(fname
, "w");
161 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
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
); }
184 } // end of while ll_iter_next
185 cs_readunlock(__func__
, &gbox_cards_lock
);
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
);
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
);
226 static uint8_t closer_path_known(uint32_t caprovid
, uint16_t id_peer
, uint8_t slot
, uint8_t distance
)
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
)
240 cs_readunlock(__func__
, &gbox_cards_lock
);
244 static uint8_t got_from_backup(uint32_t caprovid
, uint16_t id_peer
, uint8_t slot
, struct gbox_peer
*origin_peer
)
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
);
263 cs_writeunlock(__func__
, &gbox_cards_lock
);
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
274 //don't insert 0100:000000
275 if(caid_is_seca(caid
) && (!provid
))
277 //skip CAID 18XX providers
278 if(caid_is_nagra(caid
) && (provid
))
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");
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
;
295 card
->badsids
= ll_create("badsids");
296 card
->goodsids
= ll_create("goodsids");
297 card
->no_cws_returned
= 0;
298 card
->average_cw_time
= 0;
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
);
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
)
332 cs_readunlock(__func__
, &gbox_cards_lock
);
337 void gbox_delete_cards(uint8_t delete_type
, uint16_t criteria
)
339 struct gbox_card
*card
;
342 cs_writelock(__func__
, &gbox_cards_lock
);
343 LL_ITER it
= ll_iter_create(gbox_cards
);
344 while((card
= ll_iter_next(&it
)))
349 case GBOX_DELETE_FROM_PEER
:
350 if (card
->origin_peer
&& card
->origin_peer
->gbox
.id
== criteria
)
353 case GBOX_DELETE_WITH_ID
:
354 if (card
->id
.peer
== criteria
)
357 case GBOX_DELETE_WITH_TYPE
:
358 if (card
->type
== criteria
)
362 cs_log("Invalid delete type: %d in gbox_delete_cards", delete_type
);
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
);
378 static void gbox_free_list(LLIST
*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
);
393 void gbox_free_cardlist(void)
395 gbox_free_list(gbox_cards
);
396 gbox_free_list(gbox_backup_cards
);
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
;
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
; }
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");
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
);
444 }//end of ll_iter_next
446 cs_writeunlock(__func__
, &gbox_cards_lock
);
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
472 cs_writeunlock(__func__
, &gbox_cards_lock
);
475 uint8_t gbox_next_free_slot(uint16_t id
)
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
);
491 static int8_t is_already_pending(LLIST
*pending_cards
, uint16_t peer_id
, uint8_t slot
)
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
)
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
)
516 uint8_t nb_matching_crds
= 0;
517 struct gbox_good_srvid
*srvid_good
= NULL
;
518 struct gbox_bad_srvid
*srvid_bad
= NULL
;
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
);
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
))
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
;
551 if (time_since_lastcw
< GBOX_SID_CONFIRM_TIME
&& er
->gbox_ecm_status
== GBOX_ECM_NOT_ASKED
)
554 i2b_buf(2, card
->id
.peer
, send_buf
+ len2
);
555 send_buf
[len2
+ 2] = card
->id
.slot
;
563 if(nb_matching_crds
== max_cards
)
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
)
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
)
586 cs_log_dbg(D_READER
, "ID: %04X SL: %02X SID: %04X is good", card
->id
.peer
, card
->id
.slot
, srvid_good
->srvid
.sid
);
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)
600 srvid_bad
->bad_strikes
++;
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
);
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
;
619 if(!cs_malloc(&srvid_bad
, sizeof(struct gbox_bad_srvid
)))
621 cs_log("ServID allocation failed");
622 cs_writeunlock(__func__
, &gbox_cards_lock
);
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
)
639 cs_writeunlock(__func__
, &gbox_cards_lock
);
640 return nb_matching_crds
;