source: trunk/module-cccshare.c @ 5375

Last change on this file since 5375 was 5352, checked in by schlocke, 8 years ago

cccam: fixed auto refresh only for local cards, loadbalancer: do not
block timeouts if we got ecms in the past

File size: 41.9 KB
Line 
1#include "globals.h"
2
3#ifdef MODULE_CCCAM
4#include "module-cccam.h"
5#include "reader-common.h"
6#include "module-cccshare.h"
7
8static uint32_t cc_share_id = 0x64;
9static LLIST *reported_carddatas;
10//static pthread_mutex_t cc_shares_lock;
11
12static int32_t card_added_count = 0;
13static int32_t card_removed_count = 0;
14static int32_t card_dup_count = 0;
15static pthread_t share_updater_thread = 0;
16
17LLIST *get_and_lock_sharelist()
18{
19        //cs_lock(&cc_shares_lock);
20        return reported_carddatas;
21}
22
23void unlock_sharelist()
24{
25        //cs_unlock(&cc_shares_lock);
26}
27
28void add_good_bad_sids(struct s_sidtab *ptr, SIDTABBITS sidtabno, struct cc_card *card) {
29        //good sids:
30        int32_t l;
31        for (l=0;l<ptr->num_srvid;l++) {
32                struct cc_srvid *srvid;
33                cs_malloc(&srvid,sizeof(struct cc_srvid), QUITERROR);
34                srvid->sid = ptr->srvid[l];
35                srvid->ecmlen = 0; //0=undefined, also not used with "O" CCcam
36                if (!ll_contains_data(card->goodsids, srvid, sizeof(struct cc_srvid)))
37                    ll_append(card->goodsids, srvid);
38        }
39
40        //bad sids:
41        if (!sidtabno) return;
42       
43        struct s_sidtab *ptr_no;
44        int32_t n;
45       
46        for (n=0,ptr_no=cfg.sidtab; ptr_no; ptr_no=ptr_no->next,n++) {
47                if (sidtabno&((SIDTABBITS)1<<n)) {
48                        int32_t m;
49                        int32_t ok_caid = FALSE;
50                        for (m=0;m<ptr_no->num_caid;m++) { //search bad sids for this caid:
51                                if (ptr_no->caid[m] == card->caid) {
52                                        ok_caid = TRUE;
53                                        break;
54                                }
55                        }
56                        if (ok_caid) {
57                                for (l=0;l<ptr_no->num_srvid;l++) {
58                                        struct cc_srvid *srvid;
59                                        cs_malloc(&srvid,sizeof(struct cc_srvid), QUITERROR);
60                                        srvid->sid = ptr_no->srvid[l];
61                                        srvid->ecmlen = 0; //0=undefined, also not used with "O" CCcam
62                                        if (!ll_contains_data(card->badsids, srvid, sizeof(struct cc_srvid)))
63                                            ll_append(card->badsids, srvid);
64                                }
65                        }
66                }
67        }
68}
69
70void add_good_bad_sids_by_rdr(struct s_reader *rdr, struct cc_card *card) {
71
72    if (!rdr->sidtabok) return;
73   
74    struct s_sidtab *ptr;
75    int32_t n,i;
76    for (n=0,ptr=cfg.sidtab; ptr; ptr=ptr->next,n++) {
77        if (rdr->sidtabok&((SIDTABBITS)1<<n)) {
78            for (i=0; i<ptr->num_caid;i++) {
79                if (ptr->caid[i] == card->caid)
80                    add_good_bad_sids(ptr, rdr->sidtabno, card);
81            }
82        }
83    }
84}
85
86
87int32_t can_use_ext(struct cc_card *card) {
88    if (card->card_type == CT_REMOTECARD)
89        return card->is_ext;
90       
91    if (card->sidtab)
92        return (card->sidtab->num_srvid>0);
93    else
94        return ll_count(card->goodsids) && ll_count(card->badsids);
95    return 0;
96}
97
98int32_t write_card(struct cc_data *cc, uint8_t *buf, struct cc_card *card, int32_t add_own, int32_t ext, int32_t au_allowed, struct s_client *cl) {
99    memset(buf, 0, CC_MAXMSGSIZE);
100    buf[0] = card->id >> 24;
101    buf[1] = card->id >> 16;
102    buf[2] = card->id >> 8;
103    buf[3] = card->id & 0xff;
104    buf[4] = card->remote_id >> 24;
105    buf[5] = card->remote_id >> 16;
106    buf[6] = card->remote_id >> 8;
107    buf[7] = card->remote_id & 0xFF;
108    buf[8] = card->caid >> 8;
109    buf[9] = card->caid & 0xff;
110    buf[10] = card->hop;
111    buf[11] = card->reshare;
112    if (au_allowed)
113            memcpy(buf + 12, card->hexserial, 8);
114
115    //with cccam 2.2.0 we have assigned and rejected sids:
116    int32_t ofs = ext?23:21;
117
118    //write providers:
119    LL_ITER it = ll_iter_create(card->providers);
120    struct cc_provider *prov;
121    while ((prov = ll_iter_next(&it))) {
122        uint32_t prid = prov->prov;
123        buf[ofs+0] = prid >> 16;
124        buf[ofs+1] = prid >> 8;
125        buf[ofs+2] = prid & 0xFF;
126        if (au_allowed)
127                memcpy(buf + ofs + 3, prov->sa, 4);
128        buf[20]++;
129        ofs+=7;
130    }
131
132    //write sids only if cccam 2.2.x:
133    if (ext) {
134        if (card->sidtab) {
135                //good sids:
136                struct s_sidtab *ptr = card->sidtab;
137                int32_t l;
138                for (l=0;l<ptr->num_srvid;l++) {
139                    buf[ofs+0] = ptr->srvid[l] >> 8;
140                    buf[ofs+1] = ptr->srvid[l] & 0xFF;
141                    ofs+=2;
142                    buf[21]++; //nassign
143                    if (buf[21] >= 240)
144                        break;
145                }
146
147                //bad sids:
148                int32_t n;
149                for (n=0,ptr=cfg.sidtab; ptr; ptr=ptr->next,n++) {
150                        if (cl->sidtabno&((SIDTABBITS)1<<n) || card->sidtabno&((SIDTABBITS)1<<n)) {
151                                int32_t m;
152                                int32_t ok_caid = FALSE;
153                                for (m=0;m<ptr->num_caid;m++) { //search bad sids for this caid:
154                                        if (ptr->caid[m] == card->caid) {
155                                                ok_caid = TRUE;
156                                                break;
157                                        }
158                                }
159                                if (ok_caid) {
160                                        for (l=0;l<ptr->num_srvid;l++) {
161                                                buf[ofs+0] = ptr->srvid[l] >> 8;
162                                                buf[ofs+1] = ptr->srvid[l] & 0xFF;
163                                                ofs+=2;
164                                                buf[22]++; //nreject
165                                                if (buf[22] >= 240)
166                                                        break;
167                                        }
168                                }
169                        }
170                        if (buf[22] >= 240)
171                            break;
172                }
173               
174        } else {
175                //assigned sids:
176                it = ll_iter_create(card->goodsids);
177                struct cc_srvid *srvid;
178                while ((srvid = ll_iter_next(&it))) {
179                    buf[ofs+0] = srvid->sid >> 8;
180                    buf[ofs+1] = srvid->sid & 0xFF;
181                    ofs+=2;
182                    buf[21]++; //nassign
183                    if (buf[21] >= 200)
184                        break;
185                }
186       
187                //reject sids:
188                it = ll_iter_create(card->badsids);
189                while ((srvid = ll_iter_next(&it))) {
190                    buf[ofs+0] = srvid->sid >> 8;
191                    buf[ofs+1] = srvid->sid & 0xFF;
192                    ofs+=2;
193                    buf[22]++; //nreject
194                    if (buf[22] >= 200)
195                        break;
196                }
197        }
198    }
199
200    //write remote nodes
201    int32_t nremote_ofs = ofs;
202    ofs++;
203    it = ll_iter_create(card->remote_nodes);
204    uint8_t *remote_node;
205    while ((remote_node = ll_iter_next(&it))) {
206        memcpy(buf+ofs, remote_node, 8);
207        ofs+=8;
208        buf[nremote_ofs]++;
209    }
210    if (add_own) {
211        memcpy(buf+ofs, cc->node_id, 8);
212        ofs+=8;
213        buf[nremote_ofs]++;
214    }
215    return ofs;
216}
217
218
219int32_t send_card_to_clients(struct cc_card *card, struct s_client *one_client) {
220        int32_t count = 0;
221
222        uint8_t buf[CC_MAXMSGSIZE];
223
224        struct s_client *cl;
225        for (cl = one_client?one_client:first_client; cl; cl=one_client?NULL:cl->next) {
226                struct cc_data *cc = cl->cc;
227                if (cl->typ=='c' && cc && ((one_client && cc->mode != CCCAM_MODE_SHUTDOWN) || (ph[cl->ctyp].num == R_CCCAM && cc->mode == CCCAM_MODE_NORMAL))) { //CCCam-Client!
228                        int32_t is_ext = cc->cccam220 && can_use_ext(card);
229                        int32_t msg = is_ext?MSG_NEW_CARD_SIDINFO:MSG_NEW_CARD;
230                        if (card_valid_for_client(cl, card)) {
231                                int32_t usr_reshare = cl->account->cccreshare;
232                                if (usr_reshare == -1) usr_reshare = cfg.cc_reshare;
233                                int32_t usr_ignorereshare = cl->account->cccignorereshare;
234                                if (usr_ignorereshare == -1) usr_ignorereshare = cfg.cc_ignore_reshare;
235                               
236                                int32_t reader_reshare = card->origin_reader?card->rdr_reshare:usr_reshare;
237                                if (reader_reshare == -1) reader_reshare = cfg.cc_reshare;
238                                int32_t reshare = (reader_reshare < usr_reshare) ? reader_reshare : usr_reshare;
239                                int32_t new_reshare;
240                                if (card->card_type == CT_CARD_BY_SERVICE_USER)
241                                    new_reshare = usr_reshare;
242                                else if (cfg.cc_ignore_reshare || usr_ignorereshare)
243                                    new_reshare = reshare;
244                                else {
245                                    new_reshare = card->reshare;
246                                    if (card->card_type == CT_REMOTECARD)
247                                        new_reshare--;
248                                    if (new_reshare > reshare)
249                                        new_reshare = reshare;
250                                }
251                                if (new_reshare < 0)
252                                        continue;
253
254                                if (!card->id)
255                                        card->id = cc_share_id++;
256
257                                int32_t len = write_card(cc, buf, card, 1, is_ext, ll_count(cl->aureader_list), cl);
258                                //buf[10] = card->hop-1;
259                                buf[11] = new_reshare;
260
261                                if (cc_cmd_send(cl, buf, len, msg) < 0)
262                                        cc->mode = CCCAM_MODE_SHUTDOWN;
263                                count++;
264                        }
265                }
266        }
267        return count;
268}
269
270void send_remove_card_to_clients(struct cc_card *card) {
271        if (!card || !card->id)
272                return;
273               
274        uint8_t buf[4];
275        buf[0] = card->id >> 24;
276        buf[1] = card->id >> 16;
277        buf[2] = card->id >> 8;
278        buf[3] = card->id & 0xFF;
279
280        struct s_client *cl;
281        for (cl = first_client; cl; cl=cl->next) {
282                struct cc_data *cc = cl->cc;
283                if (cl->typ=='c' && cc && ph[cl->ctyp].num == R_CCCAM && cc->mode == CCCAM_MODE_NORMAL) { //CCCam-Client!
284                        if (card_valid_for_client(cl, card)) {
285                                cc_cmd_send(cl, buf, 4, MSG_CARD_REMOVED);
286                        }
287                }
288        }
289}
290
291
292/**
293 * if idents defined on an cccam reader, the cards caid+provider are checked.
294 * return 1 a) if no ident defined b) card is in identlist
295 *        0 if card is not in identlist
296 *
297 * a card is in the identlist, if the cards caid is matching and mininum a provider is matching
298 **/
299int32_t chk_ident(FTAB *ftab, struct cc_card *card) {
300
301    int32_t j, k;
302    int32_t res = 1;
303
304    if (ftab && ftab->filts) {
305        for (j = 0; j < ftab->nfilts; j++) {
306            if (ftab->filts[j].caid) {
307                res = 0;
308                if (ftab->filts[j].caid==card->caid) { //caid matches!
309
310                    int32_t nprids = ftab->filts[j].nprids;
311                    if (!nprids) // No Provider ->Ok
312                        return 1;
313
314
315                    LL_ITER it = ll_iter_create(card->providers);
316                    struct cc_provider *prov;
317
318                    while ((prov = ll_iter_next(&it))) {
319                        for (k = 0; k < nprids; k++) {
320                            uint32_t prid = ftab->filts[j].prids[k];
321                            if (prid == prov->prov) { //Provider matches
322                                return 1;
323                            }
324                        }
325                    }
326                }
327            }
328        }
329    }
330    return res;
331}
332
333int32_t cc_clear_reported_carddata(LLIST *reported_carddatas, LLIST *except,
334                int32_t send_removed) {
335        int32_t i=0;
336        LL_ITER it = ll_iter_create(reported_carddatas);
337        struct cc_card *card;
338        while ((card = ll_iter_next(&it))) {
339                struct cc_card *card2 = NULL;
340                if (except) {
341                        LL_ITER it2 = ll_iter_create(except);
342                        while ((card2 = ll_iter_next(&it2))) {
343                                if (card == card2)
344                                        break;
345                        }
346                }
347
348                if (!card2 && ll_iter_remove(&it)) { //check result of ll_iter_remove, because another thread could removed it
349                        if (send_removed)
350                                send_remove_card_to_clients(card);
351                        cc_free_card(card);
352                        i++;
353                }
354        }
355        return i;
356}
357
358int32_t cc_free_reported_carddata(LLIST *reported_carddatas, LLIST *except,
359                int32_t send_removed) {
360        int32_t i=0;
361        if (reported_carddatas) {
362                i = cc_clear_reported_carddata(reported_carddatas, except, send_removed);
363                ll_destroy(reported_carddatas);
364        }
365        return i;
366}
367
368int32_t card_valid_for_client(struct s_client *cl, struct cc_card *card) {
369
370        //Check group:
371        if (card->grp && !(card->grp & cl->grp))
372                return 0;
373
374        if (!chk_ident(&cl->ftab, card))
375                return 0;
376
377        //Check caids:
378        if (!chk_ctab(card->caid, &cl->ctab))
379                return 0;
380
381        //Check reshare
382        if (card->card_type == CT_REMOTECARD) {
383            int32_t usr_ignorereshare = cl->account->cccignorereshare;
384            if (usr_ignorereshare == -1) usr_ignorereshare = cfg.cc_ignore_reshare;
385            if (!cfg.cc_ignore_reshare && !usr_ignorereshare && !card->reshare)
386                return 0;
387        }
388               
389        //Check account maxhops:
390        if (cl->account->cccmaxhops < card->hop)
391                return 0;
392
393        //Check remote node id, if card is from there, ignore it!
394        LL_ITER it = ll_iter_create(card->remote_nodes);
395        uint8_t * node;
396        struct cc_data *cc = cl->cc;
397        while ((node=ll_iter_next(&it))) {
398                if (!memcmp(node, cc->peer_node_id, 8)) {
399                        return 0;
400                }
401        }
402
403        //Check Services:
404        if (ll_count(card->providers)) {
405            it = ll_iter_create(card->providers);
406            struct cc_provider *prov;
407            int8_t found=0;
408            while ((prov = ll_iter_next(&it))) {
409                uint32_t prid = prov->prov;
410                if (chk_srvid_by_caid_prov(cl, card->caid, prid)) {
411                    found = 1;
412                    break;
413                }
414            }
415            if (!found) return 0;
416        }
417       
418        //Check Card created by Service:
419        if (card->sidtab) {
420                struct s_sidtab *ptr;
421                int32_t j;
422                int32_t ok = !cl->sidtabok && !cl->sidtabno; //default valid if no positive services and no negative services
423                if (!ok) {
424                        if (!cl->sidtabok) // no positive services, so ok by default if no negative found
425                                ok=1;
426                               
427                        for (j=0,ptr=cfg.sidtab; ptr; ptr=ptr->next,j++) {
428                                if (ptr == card->sidtab) {
429                                        if (cl->sidtabno&((SIDTABBITS)1<<j))
430                                                return 0;
431                                        if (cl->sidtabok&((SIDTABBITS)1<<j))
432                                                ok = 1;
433                                        break;
434                                }
435                        }
436                }
437                if (!ok)
438                        return 0;
439        }
440                                       
441        return 1;
442}
443
444uint32_t get_reader_prid(struct s_reader *rdr, int32_t j) {
445    return b2i(3, &rdr->prid[j][1]);
446}
447//uint32_t get_reader_prid(struct s_reader *rdr, int32_t j) {
448//  uint32_t prid;
449//  if (!(rdr->typ & R_IS_CASCADING)) { // Real cardreaders have 4-byte Providers
450//      prid = b2i(4, &rdr->prid[j][0]);
451//      //prid = (rdr->prid[j][0] << 24) | (rdr->prid[j][1] << 16)
452//      //      | (rdr->prid[j][2] << 8) | (rdr->prid[j][3] & 0xFF);
453//  } else { // Cascading/Network-reader 3-bytes Providers
454//      prid = b2i(3, &rdr->prid[j][0]);
455//      //prid = (rdr->prid[j][0] << 16) | (rdr->prid[j][1] << 8)
456//      //      | (rdr->prid[j][2] & 0xFF);
457//
458//  }
459//  return prid;
460//}
461
462void copy_sids(LLIST *dst, LLIST *src) {
463    LL_ITER it_src = ll_iter_create(src);
464    LL_ITER it_dst = ll_iter_create(dst);
465    struct cc_srvid *srvid_src;
466    struct cc_srvid *srvid_dst;
467    while ((srvid_src=ll_iter_next(&it_src))) {
468        ll_iter_reset(&it_dst);
469        while ((srvid_dst=ll_iter_next(&it_dst))) {
470            if (sid_eq(srvid_src, srvid_dst))
471                break;
472        }
473        if (!srvid_dst) {
474            srvid_dst = cs_malloc(&srvid_dst, sizeof(struct cc_srvid), QUITERROR);
475            memcpy(srvid_dst, srvid_src, sizeof(struct cc_srvid));
476            ll_iter_insert(&it_dst, srvid_dst);
477        }
478    }
479}
480
481
482int32_t add_card_providers(struct cc_card *dest_card, struct cc_card *card,
483        int32_t copy_remote_nodes) {
484    int32_t modified = 0;
485
486    //1. Copy nonexisting providers, ignore double:
487    struct cc_provider *prov_info;
488    LL_ITER it_src = ll_iter_create(card->providers);
489    LL_ITER it_dst = ll_iter_create(dest_card->providers);
490
491    struct cc_provider *provider;
492    while ((provider = ll_iter_next(&it_src))) {
493        ll_iter_reset(&it_dst);
494        while ((prov_info = ll_iter_next(&it_dst))) {
495            if (prov_info->prov == provider->prov)
496                break;
497        }
498        if (!prov_info) {
499            struct cc_provider *prov_new = cs_malloc(&prov_new, sizeof(struct cc_provider), QUITERROR);
500            memcpy(prov_new, provider, sizeof(struct cc_provider));
501            ll_iter_insert(&it_dst, prov_new);
502            modified = 1;
503        }
504    }
505
506    if (copy_remote_nodes) {
507        //2. Copy nonexisting remote_nodes, ignoring existing:
508        it_src = ll_iter_create(card->remote_nodes);
509        it_dst = ll_iter_create(dest_card->remote_nodes);
510        uint8_t *remote_node;
511        uint8_t *remote_node2;
512        while ((remote_node = ll_iter_next(&it_src))) {
513            ll_iter_reset(&it_dst);
514            while ((remote_node2 = ll_iter_next(&it_dst))) {
515                if (memcmp(remote_node, remote_node2, 8) == 0)
516                    break;
517            }
518            if (!remote_node2) {
519                uint8_t* remote_node_new = cs_malloc(&remote_node_new, 8, QUITERROR);
520                memcpy(remote_node_new, remote_node, 8);
521                ll_iter_insert(&it_dst, remote_node_new);
522                modified = 1;
523            }
524        }
525    }
526    return modified;
527}
528
529struct cc_card *create_card(struct cc_card *card) {
530    struct cc_card *card2 = cs_malloc(&card2, sizeof(struct cc_card), QUITERROR);
531    if (card)
532        memcpy(card2, card, sizeof(struct cc_card));
533    else
534        memset(card2, 0, sizeof(struct cc_card));
535    card2->providers = ll_create();
536    card2->badsids = ll_create();
537    card2->goodsids = ll_create();
538    card2->remote_nodes = ll_create();
539
540    if (card) {
541        copy_sids(card2->goodsids, card->goodsids);
542        copy_sids(card2->badsids, card->badsids);
543        card2->id = 0;
544    }
545    else
546        set_card_timeout(card2);
547
548    return card2;
549}
550
551struct cc_card *create_card2(struct s_reader *rdr, int32_t j, uint16_t caid, uint8_t reshare) {
552
553    struct cc_card *card = create_card(NULL);
554    card->remote_id = (rdr?(rdr->cc_id << 16):0x7F7F8000)|j;
555    card->caid = caid;
556    card->reshare = reshare;
557    card->origin_reader = rdr;
558    if (rdr) {
559        card->grp = rdr->grp;
560        card->rdr_reshare = rdr->cc_reshare; //copy reshare because reader could go offline
561        card->sidtabno = rdr->sidtabno;
562        card->hop = rdr->cc_hop;
563    }
564    else card->rdr_reshare = reshare;
565    return card;
566}
567
568/**
569 * num_same_providers checks if card1 has exactly the same providers as card2
570 * returns same provider count
571 **/
572int32_t num_same_providers(struct cc_card *card1, struct cc_card *card2) {
573
574    int32_t found=0;
575
576    LL_ITER it1 = ll_iter_create(card1->providers);
577    LL_ITER it2 = ll_iter_create(card2->providers);
578
579    struct cc_provider *prov1, *prov2;
580
581    while ((prov1=ll_iter_next(&it1))) {
582
583        ll_iter_reset(&it2);
584        while ((prov2=ll_iter_next(&it2))) {
585            if (prov1->prov==prov2->prov) {
586                found++;
587                break;
588            }
589
590        }
591    }
592    return found;
593}
594
595/**
596 * equal_providers checks if card1 has exactly the same providers as card2
597 * returns 1=equal 0=different
598 **/
599int32_t equal_providers(struct cc_card *card1, struct cc_card *card2) {
600
601    if (ll_count(card1->providers) != ll_count(card2->providers))
602        return 0;
603    if (ll_count(card1->providers) == 0)
604       return 1;
605
606    LL_ITER it1 = ll_iter_create(card1->providers);
607    LL_ITER it2 = ll_iter_create(card2->providers);
608
609    struct cc_provider *prov1, *prov2;
610
611    while ((prov1=ll_iter_next(&it1))) {
612
613        ll_iter_reset(&it2);
614        while ((prov2=ll_iter_next(&it2))) {
615            if (prov1->prov==prov2->prov) {
616                break;
617            }
618
619        }
620        if (!prov2) break;
621    }
622    return (prov1 == NULL);
623}
624
625/**
626 * Adds a new card to a cardlist.
627 */
628int32_t add_card_to_serverlist(LLIST *cardlist, struct cc_card *card, int free_card) {
629
630    int32_t modified = 0;
631    LL_ITER it = ll_iter_create(cardlist);
632    struct cc_card *card2;
633
634    //Minimize all, transmit just CAID, merge providers:
635    if (cfg.cc_minimize_cards == MINIMIZE_CAID && !cfg.cc_forward_origin_card) {
636        while ((card2 = ll_iter_next(&it))) {
637            //compare caid, hexserial, cardtype and sidtab (if any):
638            if (same_card2(card, card2)) {
639                //Merge cards only if resulting providercount is smaller than CS_MAXPROV
640                int32_t nsame, ndiff, nnew;
641
642                nsame = num_same_providers(card, card2); //count same cards
643                ndiff = ll_count(card->providers)-nsame; //cound different cards, this cound will be added
644                nnew = ndiff + ll_count(card2->providers); //new card count after add. because its limited to CS_MAXPROV, dont add it
645
646                if (nnew <= CS_MAXPROV)
647                    break;
648            }
649        }
650       
651        if (!card2) { //Not found->add it:
652            if (free_card) { //Use this card
653                free_card = FALSE;
654                ll_iter_insert(&it, card);
655            } else {
656                card2 = create_card(card); //Copy card
657                card2->hop = 0;
658                ll_iter_insert(&it, card2);
659                add_card_providers(card2, card, 1); //copy providers to new card. Copy remote nodes to new card
660            }
661            modified = 1;
662
663        } else { //found, merge providers:
664            card_dup_count++;
665            add_card_providers(card2, card, 0); //merge all providers
666            ll_clear_data(card2->remote_nodes); //clear remote nodes
667            if (!card2->sidtab)
668                ll_clear_data(card2->badsids);
669        }
670    }
671
672    //Removed duplicate cards, keeping card with lower hop:
673    else if (cfg.cc_minimize_cards == MINIMIZE_HOPS && !cfg.cc_forward_origin_card) {
674        while ((card2 = ll_iter_next(&it))) {
675            //compare caid, hexserial, cardtype, sidtab (if any), providers:
676            if (same_card2(card, card2) && equal_providers(card, card2)) {
677                break;
678            }
679        }
680       
681        if (card2 && card2->hop > card->hop) { //hop is smaller, drop old card
682            ll_iter_remove(&it);
683            cc_free_card(card2);
684            card2 = NULL;
685            card_dup_count++;
686        }
687
688        if (!card2) { //Not found->add it:
689            if (free_card) { //use this card
690                free_card = FALSE;
691                ll_iter_insert(&it, card);
692            } else { 
693                card2 = create_card(card); //copy card
694                ll_iter_insert(&it, card2);
695                add_card_providers(card2, card, 1); //copy providers to new card. Copy remote nodes to new card
696            }
697            modified = 1;
698        } else { //found, merge cards (providers are same!)
699            card_dup_count++;
700            add_card_providers(card2, card, 0);
701            if (!card2->sidtab)
702                ll_clear_data(card2->badsids);
703        }
704
705    }
706    //like cccam:
707    else { //just remove duplicate cards (same ids)
708        while ((card2 = ll_iter_next(&it))) {
709            //compare remote_id, first_node, caid, hexserial, cardtype, sidtab (if any), providers:
710            if (same_card(card, card2))
711                break;
712        }
713       
714        if (card2 && card2->hop > card->hop) { //same card, if hop greater drop card
715            ll_iter_remove(&it);
716            cc_free_card(card2);
717            card2 = NULL;
718            card_dup_count++;
719        }
720        if (!card2) { //Not found, add it:
721            if (free_card) {
722                free_card = FALSE;
723                ll_iter_insert(&it, card);
724            } else {
725                card2 = create_card(card);
726                ll_iter_insert(&it, card2);
727                add_card_providers(card2, card, 1);
728            }
729            modified = 1;
730        } else { //Found, everything is same (including providers)
731            card_dup_count++;
732        }
733    }
734   
735    if (free_card)
736        cc_free_card(card);
737       
738    return modified;
739}
740
741int32_t card_timed_out(struct cc_card *card)
742{
743    int32_t res = (card->card_type != CT_REMOTECARD) && (card->timeout < time(NULL)); //local card is older than 1h?
744    if (res)
745        cs_debug_mask(D_TRACE, "card %08X timed out! refresh forced", card->id?card->id:card->origin_id);
746    return res;
747}
748           
749int32_t find_reported_card(struct cc_card *card1)
750{
751    LL_ITER it = ll_iter_create(reported_carddatas);
752    struct cc_card *card2;
753    while ((card2 = ll_iter_next(&it))) {
754        if (same_card(card1, card2) && !card_timed_out(card2)) {
755            card1->id = card2->id; //Set old id !!
756            cc_free_card(card2);
757            ll_iter_remove(&it);
758            return 1; //Old card and new card are equal!
759        }
760    }
761    return 0; //Card not found
762}
763
764/**
765* Server:
766* Adds a cccam-carddata buffer to the list of reported carddatas
767*/
768void cc_add_reported_carddata(LLIST *reported_carddatas, struct cc_card *card) {
769        ll_append(reported_carddatas, card);
770}       
771       
772int32_t report_card(struct cc_card *card, LLIST *new_reported_carddatas)
773{
774    int32_t res = 0;
775    if (!find_reported_card(card)) { //Add new card:
776
777        send_card_to_clients(card, NULL);
778
779        card_added_count++;
780    }
781    cc_add_reported_carddata(new_reported_carddatas, card);
782    return res;
783}
784
785
786/**
787 * Server:
788 * Reports all caid/providers to the connected clients
789 * returns 1=ok, 0=error
790 * cfg.cc_reshare_services  =0 CCCAM reader reshares only received cards + defined reader services
791 *              =1 CCCAM reader reshares received cards + defined services
792 *              =2 CCCAM reader reshares only defined reader-services as virtual cards
793 *              =3 CCCAM reader reshares only defined user-services as virtual cards
794 *              =4 CCCAM reader reshares only received cards
795 */
796void update_card_list() {
797    int32_t j, flt;
798
799    LLIST *server_cards = ll_create();
800    LLIST *new_reported_carddatas = ll_create();
801
802    card_added_count = 0;
803    card_removed_count = 0;
804    card_dup_count = 0;
805
806    //User-Services:
807    if (cfg.cc_reshare_services==3 && cfg.sidtab) {
808        struct s_sidtab *ptr;
809        for (j=0,ptr=cfg.sidtab; ptr; ptr=ptr->next,j++) {
810                int32_t k;
811                for (k=0;k<ptr->num_caid;k++) {
812                    struct cc_card *card = create_card2(NULL, (j<<8)|k, ptr->caid[k], cfg.cc_reshare);
813                    card->card_type = CT_CARD_BY_SERVICE_USER;
814                    card->sidtab = ptr;
815                    int32_t l;
816                    for (l=0;l<ptr->num_provid;l++) {
817                        struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);
818                        memset(prov, 0, sizeof(struct cc_provider));
819                        prov->prov = ptr->provid[l];
820                        ll_append(card->providers, prov);
821                    }
822
823                    add_card_to_serverlist(server_cards, card, TRUE);
824                }
825                flt=1;
826        }
827    }
828    else
829    {
830        struct s_reader *rdr;
831        int32_t r = 0;
832        for (rdr = first_active_reader; rdr; rdr = rdr->next) {
833            //Generate a uniq reader id:
834            if (!rdr->cc_id) {
835                rdr->cc_id = ++r;
836                struct s_reader *rdr2;
837                for (rdr2 = first_active_reader; rdr2; rdr2 = rdr2->next) {
838                    if (rdr2 != rdr && rdr2->cc_id == rdr->cc_id) {
839                        rdr2 = first_active_reader;
840                        rdr->cc_id=++r;
841                    }
842                }
843            }
844
845            flt = 0;
846
847            int32_t reshare = rdr->cc_reshare;
848            if (reshare == -1) reshare = cfg.cc_reshare;
849           
850            //Reader-Services:
851            if ((cfg.cc_reshare_services==1||cfg.cc_reshare_services==2||(!rdr->caid && rdr->typ != R_CCCAM && cfg.cc_reshare_services!=4 )) && 
852                    cfg.sidtab && (rdr->sidtabno || rdr->sidtabok)) {
853                struct s_sidtab *ptr;
854                for (j=0,ptr=cfg.sidtab; ptr; ptr=ptr->next,j++) {
855                    if (!(rdr->sidtabno&((SIDTABBITS)1<<j)) && (rdr->sidtabok&((SIDTABBITS)1<<j))) {
856                        int32_t k;
857                        for (k=0;k<ptr->num_caid;k++) {
858                            struct cc_card *card = create_card2(rdr, (j<<8)|k, ptr->caid[k], reshare);
859                            card->card_type = CT_CARD_BY_SERVICE_READER;
860                            card->sidtab = ptr;
861                            int32_t l;
862                            for (l=0;l<ptr->num_provid;l++) {
863                                struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);
864                                prov->prov = ptr->provid[l];
865                                ll_append(card->providers, prov);
866                            }
867
868                            if (chk_ident(&rdr->ftab, card) && chk_ctab(card->caid, &rdr->ctab)) {
869                                if (!rdr->audisabled)
870                                    cc_UA_oscam2cccam(rdr->hexserial, card->hexserial, card->caid);
871                       
872                                add_card_to_serverlist(server_cards, card, TRUE);
873                                flt=1;
874                            }
875                            else 
876                                cc_free_card(card);
877                        }
878                    }
879                }
880            }
881
882            //Filts by Hardware readers:
883            if ((rdr->typ != R_CCCAM) && rdr->ftab.filts && !flt) {
884                for (j = 0; j < CS_MAXFILTERS; j++) {
885                    if (rdr->ftab.filts[j].caid) {
886                        uint16_t caid = rdr->ftab.filts[j].caid;
887                        struct cc_card *card = create_card2(rdr, j, caid, reshare);
888                        card->card_type = CT_LOCALCARD;
889                       
890                        //Setting UA: (Unique Address):
891                        if (!rdr->audisabled)
892                                cc_UA_oscam2cccam(rdr->hexserial, card->hexserial, caid);
893                        //cs_log("Ident CCcam card report caid: %04X readr %s subid: %06X", rdr->ftab.filts[j].caid, rdr->label, rdr->cc_id);
894                        int32_t k;
895                        for (k = 0; k < rdr->ftab.filts[j].nprids; k++) {
896                            struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);
897                            prov->prov = rdr->ftab.filts[j].prids[k];
898
899                            //cs_log("Ident CCcam card report provider: %02X%02X%02X", buf[21 + (k*7)]<<16, buf[22 + (k*7)], buf[23 + (k*7)]);
900                            if (!rdr->audisabled) {
901                                int32_t l;
902                                for (l = 0; l < rdr->nprov; l++) {
903                                    uint32_t rprid = get_reader_prid(rdr, l);
904                                    if (rprid == prov->prov)
905                                        cc_SA_oscam2cccam(&rdr->sa[l][0], prov->sa);
906                                }
907                            }
908
909                            ll_append(card->providers, prov);
910                        }
911
912                        add_good_bad_sids_by_rdr(rdr, card);
913                        add_card_to_serverlist(server_cards, card, TRUE);
914                        flt = 1;
915                    }
916                }
917            }
918
919            if ((rdr->typ != R_CCCAM) && !rdr->caid && !flt) {
920                for (j = 0; j < CS_MAXCAIDTAB; j++) {
921                    //cs_log("CAID map CCcam card report caid: %04X cmap: %04X", rdr->ctab.caid[j], rdr->ctab.cmap[j]);
922                    uint16_t lcaid = rdr->ctab.caid[j];
923
924                    if (!lcaid || (lcaid == 0xFFFF))
925                        lcaid = rdr->ctab.cmap[j];
926
927                    if (lcaid && (lcaid != 0xFFFF)) {
928                        struct cc_card *card = create_card2(rdr, j, lcaid, reshare);
929                        card->card_type = CT_CARD_BY_CAID;
930                        if (!rdr->audisabled)
931                            cc_UA_oscam2cccam(rdr->hexserial, card->hexserial, lcaid);
932
933                        add_good_bad_sids_by_rdr(rdr, card);
934                        add_card_to_serverlist(server_cards, card, TRUE);
935                        flt = 1;
936                    }
937                }
938            }
939
940            if ((rdr->typ != R_CCCAM) && rdr->ctab.caid[0] && !flt) {
941                //cs_log("tcp_connected: %d card_status: %d ", rdr->tcp_connected, rdr->card_status);
942                int32_t c;
943                if (rdr->tcp_connected || rdr->card_status == CARD_INSERTED) {
944                    for (c=0;c<CS_MAXCAIDTAB;c++) 
945                    {
946                        uint16_t caid = rdr->ctab.caid[c];
947                        if (!caid) break;
948                       
949                        struct cc_card *card = create_card2(rdr, c, caid, reshare);
950                        card->card_type = CT_CARD_BY_CAID;
951                   
952                        if (!rdr->audisabled)
953                                cc_UA_oscam2cccam(rdr->hexserial, card->hexserial, caid);
954                        for (j = 0; j < rdr->nprov; j++) {
955                         uint32_t prid = get_reader_prid(rdr, j);
956                            struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);
957                            prov->prov = prid;
958                            //cs_log("Ident CCcam card report provider: %02X%02X%02X", buf[21 + (k*7)]<<16, buf[22 + (k*7)], buf[23 + (k*7)]);
959                            if (!rdr->audisabled) {
960                                //Setting SA (Shared Addresses):
961                                cc_SA_oscam2cccam(rdr->sa[j], prov->sa);
962                            }
963                            ll_append(card->providers, prov);
964                            //cs_log("Main CCcam card report provider: %02X%02X%02X%02X", buf[21+(j*7)], buf[22+(j*7)], buf[23+(j*7)], buf[24+(j*7)]);
965                        }
966                        add_good_bad_sids_by_rdr(rdr, card);
967                        add_card_to_serverlist(server_cards, card, TRUE);
968                        flt = 1;
969                    }
970                }
971            }
972
973
974            if ((rdr->typ != R_CCCAM) && rdr->caid && !flt) {
975                //cs_log("tcp_connected: %d card_status: %d ", rdr->tcp_connected, rdr->card_status);
976                if (rdr->tcp_connected || rdr->card_status == CARD_INSERTED) {
977                    uint16_t caid = rdr->caid;
978                    struct cc_card *card = create_card2(rdr, 1, caid, reshare);
979                    card->card_type = CT_CARD_BY_CAID;
980               
981                    if (!rdr->audisabled)
982                        cc_UA_oscam2cccam(rdr->hexserial, card->hexserial, caid);
983                    for (j = 0; j < rdr->nprov; j++) {
984                        uint32_t prid = get_reader_prid(rdr, j);
985                        struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);
986                        prov->prov = prid;
987                        //cs_log("Ident CCcam card report provider: %02X%02X%02X", buf[21 + (k*7)]<<16, buf[22 + (k*7)], buf[23 + (k*7)]);
988                        if (!rdr->audisabled) {
989                            //Setting SA (Shared Addresses):
990                            cc_SA_oscam2cccam(rdr->sa[j], prov->sa);
991                        }
992                        ll_append(card->providers, prov);
993                        //cs_log("Main CCcam card report provider: %02X%02X%02X%02X", buf[21+(j*7)], buf[22+(j*7)], buf[23+(j*7)], buf[24+(j*7)]);
994                    }
995                    add_good_bad_sids_by_rdr(rdr, card);
996                    add_card_to_serverlist(server_cards, card, TRUE);
997                }
998            }
999
1000            if (rdr->typ == R_CCCAM && (cfg.cc_reshare_services<2 || cfg.cc_reshare_services==4) && rdr->card_status != CARD_FAILURE) {
1001
1002                cs_debug_mask(D_TRACE, "asking reader %s for cards...", rdr->label);
1003
1004                struct cc_card *card;
1005                struct s_client *rc = rdr->client;
1006                struct cc_data *rcc = rc?rc->cc:NULL;
1007
1008                int32_t count = 0;
1009                int32_t notlocked = 1;
1010                while (rcc && rcc->cards && rcc->mode == CCCAM_MODE_NORMAL &&
1011                    (notlocked=cs_trylock(&rcc->cards_busy))) {
1012                    cs_debug_mask(D_TRACE, "trylock asking reader %s cards", rdr->label);
1013                    cs_sleepms(50);
1014                }
1015               
1016                if (!notlocked) {
1017                    LL_ITER it = ll_iter_create(rcc->cards);
1018                    while ((card = ll_iter_next(&it))) {
1019                        if (chk_ctab(card->caid, &rdr->ctab)) {
1020                            int32_t ignore = 0;
1021
1022                            LL_ITER it2 = ll_iter_create(card->providers);
1023                            struct cc_provider *prov;
1024                            while ((prov = ll_iter_next(&it2))) {
1025                                uint32_t prid = prov->prov;
1026                                if (!chk_srvid_by_caid_prov(rdr->client, card->caid, prid)) {
1027                                    ignore = 1;
1028                                    break;
1029                                }
1030                            }
1031
1032                            if (!ignore) { //Filtered by service
1033                                add_card_to_serverlist(server_cards, card, FALSE);
1034                                count++;
1035                            }
1036                        }
1037                    }
1038                    cs_unlock(&rcc->cards_busy);
1039                }
1040                else
1041                    cs_debug_mask(D_TRACE, "reader %s not active! (mode=%d)", rdr->label, rcc?rcc->mode:-1);
1042                cs_debug_mask(D_TRACE, "got %d cards from %s", count, rdr->label);
1043            }
1044        }
1045    }
1046
1047    //report reshare cards:
1048    //cs_debug_mask(D_TRACE, "%s reporting %d cards", getprefix(), ll_count(server_cards));
1049    LL_ITER it = ll_iter_create(server_cards);
1050    struct cc_card *card;
1051    while ((card = ll_iter_next(&it))) {
1052            //cs_debug_mask(D_TRACE, "%s card %d caid %04X hop %d", getprefix(), card->id, card->caid, card->hop);
1053
1054            report_card(card, new_reported_carddatas);
1055            ll_iter_remove(&it);
1056    }
1057    cc_free_cardlist(server_cards, TRUE);
1058
1059    //remove unsed, remaining cards:
1060    card_removed_count += cc_free_reported_carddata(reported_carddatas, new_reported_carddatas, TRUE);
1061    reported_carddatas = new_reported_carddatas;
1062
1063    cs_debug_mask(D_TRACE, "reported/updated +%d/-%d/dup %d of %d cards to sharelist",
1064            card_added_count, card_removed_count, card_dup_count, ll_count(reported_carddatas));
1065}
1066
1067int32_t cc_srv_report_cards(struct s_client *cl) {
1068    struct cc_data *cc = cl->cc;
1069    LL_ITER it = ll_iter_create(reported_carddatas);
1070    struct cc_card *card;
1071    while (cl->cc && cc->mode != CCCAM_MODE_SHUTDOWN && (card = ll_iter_next(&it))) {
1072        send_card_to_clients(card, cl);
1073    }
1074
1075    return cl->cc && cc->mode != CCCAM_MODE_SHUTDOWN;
1076}
1077
1078void refresh_shares()
1079{
1080        //cs_lock(&cc_shares_lock);
1081        update_card_list();
1082        //cs_unlock(&cc_shares_lock);
1083}
1084
1085#define DEFAULT_INTERVAL 30
1086
1087void share_updater()
1088{
1089        int32_t i = DEFAULT_INTERVAL + cfg.waitforcards_extra_delay/1000;
1090        uint32_t last_check = 0;
1091        uint32_t last_card_check = 0;
1092        uint32_t card_count = 0;
1093        while (TRUE) {
1094                if ((i > 0 || cfg.cc_forward_origin_card) && card_count < 100) { //fast refresh only if we have less cards
1095                        cs_sleepms(1000);
1096                        i--;
1097                }
1098                else if (i > 0) {
1099                        cs_sleepms(6000); //1s later than garbage collector because this list uses much space
1100                        i--;
1101                }
1102                else
1103                {
1104                        if (cfg.cc_update_interval <= 10)
1105                                cfg.cc_update_interval = DEFAULT_UPDATEINTERVAL;
1106                        cs_sleepms(cfg.cc_update_interval*1000);
1107                }
1108               
1109                uint32_t cur_check = 0;
1110                uint32_t cur_card_check = 0;
1111                struct s_reader *rdr;
1112                for (rdr=first_active_reader; rdr; rdr=rdr->next) {
1113                        if (rdr->client && rdr->client->cc) { //check cccam-cardlist:
1114                                struct cc_data *cc = rdr->client->cc;
1115                                cur_card_check += cc->card_added_count;
1116                                cur_card_check += cc->card_removed_count;
1117                                card_count += ll_count(cc->cards);
1118                        }
1119                        cur_check = crc32(cur_check, (uint8_t*)&rdr->tcp_connected, sizeof(rdr->tcp_connected));
1120                        cur_check = crc32(cur_check, (uint8_t*)&rdr->card_status, sizeof(rdr->card_status));
1121                        cur_check = crc32(cur_check, (uint8_t*)&rdr->hexserial, 8); //check hexserial
1122                        cur_check = crc32(cur_check, (uint8_t*)&rdr->prid, rdr->nprov * sizeof(rdr->prid[0])); //check providers
1123                        cur_check = crc32(cur_check, (uint8_t*)&rdr->sa, rdr->nprov * sizeof(rdr->sa[0])); //check provider-SA
1124                        cur_check = crc32(cur_check, (uint8_t*)&rdr->ftab, sizeof(FTAB)); //check reader
1125                        cur_check = crc32(cur_check, (uint8_t*)&rdr->ctab, sizeof(CAIDTAB)); //check caidtab
1126                        cur_check = crc32(cur_check, (uint8_t*)&rdr->fchid, sizeof(FTAB)); //check chids
1127                        cur_check = crc32(cur_check, (uint8_t*)&rdr->sidtabok, sizeof(rdr->sidtabok)); //check assigned ok services
1128                        cur_check = crc32(cur_check, (uint8_t*)&rdr->sidtabno, sizeof(rdr->sidtabno)); //check assigned no services
1129                }
1130               
1131                //check defined services:
1132                struct s_sidtab *ptr;
1133                for (ptr=cfg.sidtab; ptr; ptr=ptr->next) {
1134                        cur_check = crc32(cur_check, (uint8_t*)ptr, sizeof(struct s_sidtab));
1135                }
1136               
1137                //update cardlist if reader config has changed, also set interval to 1s / 30times
1138                if (cur_check != last_check) {
1139                        i = DEFAULT_INTERVAL;
1140                        cs_debug_mask(D_TRACE, "share-update [1] %lu %lu", cur_check, last_check); 
1141                        refresh_shares();
1142                        last_check = cur_check;
1143                        last_card_check = cur_card_check;
1144                }
1145                //update cardlist if cccam cards has changed:
1146                else if (cur_card_check != last_card_check) {
1147                        cs_debug_mask(D_TRACE, "share-update [2] %lu %lu", cur_card_check, last_card_check); 
1148                        refresh_shares();
1149                        last_card_check = cur_card_check;
1150                }
1151        }
1152}
1153
1154int32_t compare_cards_by_hop(struct cc_card **pcard1, struct cc_card **pcard2)
1155{
1156    struct cc_card *card1 = (*pcard1), *card2 = (*pcard2);
1157   
1158    int32_t res = card1->hop - card2->hop;
1159    if (res) return res;
1160    res = card1->caid - card2->caid;
1161    if (res) return res;
1162    res = card1->reshare - card2->reshare;
1163    if (res) return res;
1164    res = card1->id - card2->id;
1165    return res; 
1166}
1167
1168int32_t compare_cards_by_hop_r(struct cc_card **pcard1, struct cc_card **pcard2)
1169{
1170    return -compare_cards_by_hop(pcard1, pcard2);
1171}
1172
1173void sort_cards_by_hop(LLIST *cards, int32_t reverse)
1174{
1175    if (reverse)
1176        ll_sort(cards, compare_cards_by_hop_r);
1177    else
1178        ll_sort(cards, compare_cards_by_hop);
1179}
1180
1181void init_share() {
1182
1183        reported_carddatas = ll_create();
1184        //pthread_mutex_init(&cc_shares_lock, NULL);
1185
1186        share_updater_thread = 0;
1187        pthread_t temp;
1188        pthread_attr_t attr;
1189        pthread_attr_init(&attr);
1190#ifndef TUXBOX
1191        pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE);
1192#endif
1193        if (pthread_create(&temp, &attr, (void*)&share_updater, NULL))
1194                cs_log("ERROR: can't create share updater thread!");
1195        else {
1196                cs_debug_mask(D_TRACE, "share updater thread started");
1197                pthread_detach(temp);
1198                share_updater_thread = temp;
1199        }
1200        pthread_attr_destroy(&attr);
1201}           
1202
1203void done_share() {
1204        if (share_updater_thread) {
1205                pthread_cancel(share_updater_thread);
1206                share_updater_thread = 0;
1207               
1208                cc_free_reported_carddata(reported_carddatas, NULL, 0);
1209                //cs_unlock(&cc_shares_lock);
1210                //pthread_mutex_destroy(&cc_shares_lock);
1211        }
1212}
1213#endif
Note: See TracBrowser for help on using the repository browser.