Changeset 4747 for trunk/module-cccam.c
- Timestamp:
- 02/24/11 22:19:46 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/module-cccam.c
r4744 r4747 6 6 #include "reader-common.h" 7 7 #include <poll.h> 8 9 extern int pthread_mutexattr_settype(pthread_mutexattr_t *__attr, int __kind); //Needs extern defined??? 8 #include "module-cccshare.h" 10 9 11 10 //Mode names for CMD_05 command: … … 17 16 18 17 static uint8 cc_node_id[8]; 19 static uint32 cc_share_id = 0x64;20 18 21 19 #define getprefix() ((struct cc_data *)(cl->cc))->prefix 22 #define QUITERROR 123 20 24 21 void cc_init_crypt(struct cc_crypt_block *block, uint8 *key, int len) { … … 329 326 cl->pfd = 0; 330 327 } 331 328 332 329 cc->just_logged_in = 0; 333 330 } … … 1356 1353 } 1357 1354 1358 /**1359 * Server:1360 * Adds a cccam-carddata buffer to the list of reported carddatas1361 */1362 void cc_add_reported_carddata(LLIST *reported_carddatas, struct cc_card *card) {1363 ll_append(reported_carddatas, card);1364 }1365 1366 1355 struct cc_card *cc_get_card_by_id(uint32 card_id, LLIST *cards) { 1367 1356 if (!cards) … … 1378 1367 } 1379 1368 1380 int cc_clear_reported_carddata(struct s_client *cl, LLIST *reported_carddatas, LLIST *except,1381 int send_removed) {1382 int i=0;1383 LL_ITER *it = ll_iter_create(reported_carddatas);1384 struct cc_card *card;1385 while ((card = ll_iter_next(it))) {1386 struct cc_card *card2 = NULL;1387 if (except) {1388 LL_ITER *it2 = ll_iter_create(except);1389 while ((card2 = ll_iter_next(it2))) {1390 if (card == card2)1391 break;1392 }1393 ll_iter_release(it2);1394 }1395 1396 if (!card2) {1397 if (send_removed) {1398 uint8 buf[4];1399 buf[0] = card->id >>24;1400 buf[1] = card->id >>16;1401 buf[2] = card->id >>8;1402 buf[3] = card->id & 0xFF;1403 cc_cmd_send(cl, buf, 4, MSG_CARD_REMOVED);1404 }1405 cc_free_card(card);1406 i++;1407 }1408 ll_iter_remove(it);1409 }1410 ll_iter_release(it);1411 return i;1412 }1413 1414 int cc_free_reported_carddata(struct s_client *cl, LLIST *reported_carddatas, LLIST *except,1415 int send_removed) {1416 int i=0;1417 if (reported_carddatas) {1418 i = cc_clear_reported_carddata(cl, reported_carddatas, except, send_removed);1419 ll_destroy(reported_carddatas);1420 }1421 return i;1422 }1423 1424 1369 void cc_free_cardlist(LLIST *card_list, int destroy_list) { 1425 1370 if (card_list) { … … 1447 1392 cl->cc=NULL; 1448 1393 cc_free_cardlist(cc->cards, TRUE); 1449 cc_free_reported_carddata(c l, cc->reported_carddatas, NULL, FALSE);1394 cc_free_reported_carddata(cc->reported_carddatas, NULL, FALSE); 1450 1395 ll_destroy_data(cc->pending_emms); 1451 1396 if (cc->extended_ecm_idx) … … 1622 1567 } 1623 1568 1624 #define READ_CARD_TIMEOUT 1001625 1626 int write_card(struct cc_data *cc, uint8 *buf, struct cc_card *card, int add_own, int ext, int au_allowed) {1627 memset(buf, 0, CC_MAXMSGSIZE);1628 buf[0] = card->id >> 24;1629 buf[1] = card->id >> 16;1630 buf[2] = card->id >> 8;1631 buf[3] = card->id & 0xff;1632 buf[4] = card->remote_id >> 24;1633 buf[5] = card->remote_id >> 16;1634 buf[6] = card->remote_id >> 8;1635 buf[7] = card->remote_id & 0xFF;1636 buf[8] = card->caid >> 8;1637 buf[9] = card->caid & 0xff;1638 buf[10] = card->hop;1639 buf[11] = card->maxdown;1640 if (au_allowed)1641 memcpy(buf + 12, card->hexserial, 8);1642 1643 //with cccam 2.2.0 we have assigned and rejected sids:1644 int ofs = ext?23:21;1645 1646 //write providers:1647 LL_ITER *it = ll_iter_create(card->providers);1648 struct cc_provider *prov;1649 while ((prov = ll_iter_next(it))) {1650 ulong prid = prov->prov;1651 buf[ofs+0] = prid >> 16;1652 buf[ofs+1] = prid >> 8;1653 buf[ofs+2] = prid & 0xFF;1654 memcpy(buf + ofs + 3, prov->sa, 4);1655 buf[20]++;1656 ofs+=7;1657 }1658 ll_iter_release(it);1659 1660 //write sids only if cccam 2.2.x:1661 if (ext) {1662 //assigned sids:1663 it = ll_iter_create(card->goodsids);1664 struct cc_srvid *srvid;1665 while ((srvid = ll_iter_next(it))) {1666 buf[ofs+0] = srvid->sid >> 8;1667 buf[ofs+1] = srvid->sid & 0xFF;1668 ofs+=2;1669 buf[21]++; //nassign1670 if (buf[21] > 250)1671 break;1672 }1673 ll_iter_release(it);1674 1675 //reject sids:1676 it = ll_iter_create(card->badsids);1677 while ((srvid = ll_iter_next(it))) {1678 buf[ofs+0] = srvid->sid >> 8;1679 buf[ofs+1] = srvid->sid & 0xFF;1680 ofs+=2;1681 buf[22]++; //nreject1682 if (buf[22] > 250)1683 break;1684 }1685 ll_iter_release(it);1686 }1687 1688 //write remote nodes1689 int nremote_ofs = ofs;1690 ofs++;1691 it = ll_iter_create(card->remote_nodes);1692 uint8 *remote_node;1693 while ((remote_node = ll_iter_next(it))) {1694 memcpy(buf+ofs, remote_node, 8);1695 ofs+=8;1696 buf[nremote_ofs]++;1697 }1698 ll_iter_release(it);1699 if (add_own) {1700 memcpy(buf+ofs, cc->node_id, 8);1701 ofs+=8;1702 buf[nremote_ofs]++;1703 }1704 return ofs;1705 }1706 1707 /**1708 * if idents defined on an cccam reader, the cards caid+provider are checked.1709 * return 1 a) if no ident defined b) card is in identlist1710 * 0 if card is not in identlist1711 *1712 * a card is in the identlist, if the cards caid is matching and mininum a provider is matching1713 **/1714 int chk_ident(FTAB *ftab, struct cc_card *card) {1715 1716 int j, k;1717 int res = 1;1718 1719 if (ftab && ftab->filts) {1720 for (j = 0; j < ftab->nfilts; j++) {1721 if (ftab->filts[j].caid) {1722 res = 0;1723 if (ftab->filts[j].caid==card->caid) { //caid matches!1724 1725 int nprids = ftab->filts[j].nprids;1726 if (!nprids) // No Provider ->Ok1727 return 1;1728 1729 1730 LL_ITER *it = ll_iter_create(card->providers);1731 struct cc_provider *prov;1732 1733 while ((prov = ll_iter_next(it))) {1734 for (k = 0; k < nprids; k++) {1735 ulong prid = ftab->filts[j].prids[k];1736 if (prid == prov->prov) { //Provider matches1737 ll_iter_release(it);1738 return 1;1739 }1740 }1741 }1742 ll_iter_release(it);1743 }1744 }1745 }1746 }1747 return res;1748 }1749 1750 1751 int card_valid_for_client(struct s_client *cl, struct cc_card *card) {1752 1753 struct s_reader *rdr = card->origin_reader;1754 //Check group:1755 if (!(rdr->grp & cl->grp))1756 return 0;1757 1758 if (!chk_ident(&cl->ftab, card) || (rdr && !chk_ident(&rdr->ftab, card)))1759 return 0;1760 1761 //Check caids:1762 if (!chk_ctab(card->caid, &cl->ctab) || (rdr && !chk_ctab(card->caid, &rdr->ctab)))1763 return 0;1764 1765 //Check reshare/maxdown:1766 if ((cfg.cc_ignore_reshare || cl->account->cccignorereshare || card->maxdown > 0)) {1767 int ignore = 0;1768 1769 //Check Services:1770 LL_ITER *it2 = ll_iter_create(card->providers);1771 struct cc_provider *prov;1772 while ((prov = ll_iter_next(it2))) {1773 ulong prid = prov->prov;1774 if (!chk_srvid_by_caid_prov(cl, card->caid, prid) ||1775 !chk_srvid_by_caid_prov(rdr->client, card->caid, prid)) {1776 ignore = 1;1777 break;1778 }1779 }1780 ll_iter_release(it2);1781 return !ignore;1782 }1783 1784 return 0;1785 }1786 1787 int send_card_to_clients(struct cc_card *card, struct s_client *one_client) {1788 int count = 0;1789 if (!one_client)1790 cs_debug_mask(D_TRACE, "forwarding new card: %08X caid %04X", card->id, card->caid);1791 1792 if (cfg.cc_minimize_cards == MINIMIZE_TRANSPARENT) { //TRANSPARENT MODE1793 uint8 buf[CC_MAXMSGSIZE];1794 1795 struct s_client *cl;1796 for (cl = one_client?one_client:first_client; cl; cl=one_client?NULL:cl->next) {1797 struct cc_data *cc = cl->cc;1798 if (ph[cl->ctyp].num == R_CCCAM && cc) { //CCCam-Client!1799 if (card_valid_for_client(cl, card)) {1800 1801 int usr_reshare = cl->account->cccreshare;1802 int usr_ignorereshare = cl->account->cccignorereshare;1803 1804 int reader_reshare = card->origin_reader->cc_reshare;1805 int reshare = (reader_reshare < usr_reshare) ? reader_reshare : usr_reshare;1806 if (reshare < 0)1807 continue;1808 1809 int new_reshare =1810 ( cfg.cc_ignore_reshare || usr_ignorereshare ) ? reshare1811 : (card->maxdown - 1);1812 if (new_reshare > reshare)1813 new_reshare = reshare;1814 1815 int len = write_card(cc, buf, card, 1, cc->cccam220, ll_count(cl->aureader_list));1816 if (!card->internal_id)1817 card->internal_id = cc_share_id++;1818 1819 buf[0] = card->internal_id >> 24;1820 buf[1] = card->internal_id >> 16;1821 buf[2] = card->internal_id >> 8;1822 buf[3] = card->internal_id & 0xFF;1823 //buf[10] = card->hop-1;1824 buf[11] = new_reshare;1825 1826 cc_cmd_send(cl, buf, len, cc->cccam220?MSG_NEW_CARD_SIDINFO:MSG_NEW_CARD);1827 count++;1828 }1829 }1830 }1831 }1832 return count;1833 }1834 1835 void send_remove_card_to_clients(struct cc_card *card) {1836 if (cfg.cc_minimize_cards == MINIMIZE_TRANSPARENT) { //TRANSPARENT MODE1837 uint8 buf[4];1838 buf[0] = card->internal_id >> 24;1839 buf[1] = card->internal_id >> 16;1840 buf[2] = card->internal_id >> 8;1841 buf[3] = card->internal_id & 0xFF;1842 1843 struct s_client *cl;1844 for (cl = first_client; cl; cl=cl->next) {1845 if (cl->ctyp == R_CCCAM && cl->cc) { //CCCam-Client!1846 if (card_valid_for_client(cl, card)) {1847 cc_cmd_send(cl, buf, 4, MSG_CARD_REMOVED);1848 }1849 }1850 }1851 }1852 }1853 1854 1855 1569 void cc_card_removed(struct s_client *cl, uint32 shareid) { 1856 1570 struct cc_data *cc = cl->cc; … … 1869 1583 } 1870 1584 free_extended_ecm_idx_by_card(cl, card); 1871 send_remove_card_to_clients(card);1872 1585 cc_free_card(card); 1873 cc->cards_modified++;1874 1586 //break; 1875 1587 } … … 2091 1803 card->time = time((time_t) 0); 2092 1804 if (!old_card) { 2093 card->internal_id = cc_share_id++;1805 card->card_type = CT_REMOTECARD; 2094 1806 card->hop++; //inkrementing hop 2095 1807 ll_append(cc->cards, card); 2096 1808 set_au_data(cl, rdr, card, NULL); 2097 cc->cards_modified++;2098 send_card_to_clients(card, NULL);2099 1809 } 2100 1810 } … … 2718 2428 } 2719 2429 2720 /**2721 * This function checks for hexserial changes on cards.2722 * We update the share-list if a card has changed2723 */2724 ulong get_reader_hexserial_crc(struct s_client *UNUSED(cl)) {2725 ulong crc = 0;2726 struct s_reader *rdr;2727 for (rdr = first_active_reader; rdr; rdr = rdr->next) {2728 if (rdr->client && !rdr->audisabled)2729 crc += crc32(0, rdr->hexserial, 8);2730 }2731 return crc;2732 }2733 2734 ulong get_reader_prid(struct s_reader *rdr, int j) {2735 return b2i(4, rdr->prid[j]);2736 }2737 //ulong get_reader_prid(struct s_reader *rdr, int j) {2738 // ulong prid;2739 // if (!(rdr->typ & R_IS_CASCADING)) { // Real cardreaders have 4-byte Providers2740 // prid = b2i(4, &rdr->prid[j][0]);2741 // //prid = (rdr->prid[j][0] << 24) | (rdr->prid[j][1] << 16)2742 // // | (rdr->prid[j][2] << 8) | (rdr->prid[j][3] & 0xFF);2743 // } else { // Cascading/Network-reader 3-bytes Providers2744 // prid = b2i(3, &rdr->prid[j][0]);2745 // //prid = (rdr->prid[j][0] << 16) | (rdr->prid[j][1] << 8)2746 // // | (rdr->prid[j][2] & 0xFF);2747 //2748 // }2749 // return prid;2750 //}2751 2752 void copy_sids(LLIST *dst, LLIST *src) {2753 LL_ITER *it_src = ll_iter_create(src);2754 LL_ITER *it_dst = ll_iter_create(dst);2755 struct cc_srvid *srvid_src;2756 struct cc_srvid *srvid_dst;2757 while ((srvid_src=ll_iter_next(it_src))) {2758 ll_iter_reset(it_dst);2759 while ((srvid_dst=ll_iter_next(it_dst))) {2760 if (sid_eq(srvid_src, srvid_dst))2761 break;2762 }2763 if (!srvid_dst) {2764 srvid_dst = cs_malloc(&srvid_dst, sizeof(struct cc_srvid), QUITERROR);2765 memcpy(srvid_dst, srvid_src, sizeof(struct cc_srvid));2766 ll_iter_insert(it_dst, srvid_dst);2767 }2768 }2769 ll_iter_release(it_dst);2770 ll_iter_release(it_src);2771 }2772 2773 int add_card_providers(struct cc_card *dest_card, struct cc_card *card,2774 int copy_remote_nodes) {2775 int modified = 0;2776 2777 //1. Copy nonexisting providers, ignore double:2778 struct cc_provider *prov_info;2779 LL_ITER *it_src = ll_iter_create(card->providers);2780 LL_ITER *it_dst = ll_iter_create(dest_card->providers);2781 2782 struct cc_provider *provider;2783 while ((provider = ll_iter_next(it_src))) {2784 ll_iter_reset(it_dst);2785 while ((prov_info = ll_iter_next(it_dst))) {2786 if (prov_info->prov == provider->prov)2787 break;2788 }2789 if (!prov_info) {2790 struct cc_provider *prov_new = cs_malloc(&prov_new, sizeof(struct cc_provider), QUITERROR);2791 memcpy(prov_new, provider, sizeof(struct cc_provider));2792 ll_iter_insert(it_dst, prov_new);2793 modified = 1;2794 }2795 }2796 ll_iter_release(it_dst);2797 ll_iter_release(it_src);2798 2799 if (copy_remote_nodes) {2800 //2. Copy nonexisting remote_nodes, ignoring existing:2801 it_src = ll_iter_create(card->remote_nodes);2802 it_dst = ll_iter_create(dest_card->remote_nodes);2803 uint8 *remote_node;2804 uint8 *remote_node2;2805 while ((remote_node = ll_iter_next(it_src))) {2806 ll_iter_reset(it_dst);2807 while ((remote_node2 = ll_iter_next(it_dst))) {2808 if (memcmp(remote_node, remote_node2, 8) == 0)2809 break;2810 }2811 if (!remote_node2) {2812 uint8* remote_node_new = cs_malloc(&remote_node_new, 8, QUITERROR);2813 memcpy(remote_node_new, remote_node, 8);2814 ll_iter_insert(it_dst, remote_node_new);2815 modified = 1;2816 }2817 }2818 ll_iter_release(it_dst);2819 ll_iter_release(it_src);2820 }2821 return modified;2822 }2823 2824 struct cc_card *create_card(struct cc_card *card) {2825 struct cc_card *card2 = cs_malloc(&card2, sizeof(struct cc_card), QUITERROR);2826 if (card)2827 memcpy(card2, card, sizeof(struct cc_card));2828 else2829 memset(card2, 0, sizeof(struct cc_card));2830 card2->providers = ll_create();2831 card2->badsids = ll_create();2832 card2->goodsids = ll_create();2833 card2->remote_nodes = ll_create();2834 2835 if (card) {2836 copy_sids(card2->goodsids, card->goodsids);2837 copy_sids(card2->badsids, card->badsids);2838 card2->origin_reader = card->origin_reader;2839 card2->origin_id = card->id;2840 }2841 2842 return card2;2843 }2844 2845 struct cc_card *create_card2(struct s_reader *rdr, int j, uint16 caid, uint8 hop, uint8 reshare) {2846 2847 struct cc_card *card = create_card(NULL);2848 card->remote_id = (rdr?(rdr->cc_id << 16):0x7F)|j;2849 card->caid = caid;2850 card->hop = hop;2851 card->maxdown = reshare;2852 card->origin_reader = rdr;2853 return card;2854 }2855 2856 /**2857 * num_same_providers checks if card1 has exactly the same providers as card22858 * returns same provider count2859 **/2860 int num_same_providers(struct cc_card *card1, struct cc_card *card2) {2861 2862 int found=0;2863 2864 LL_ITER *it1 = ll_iter_create(card1->providers);2865 LL_ITER *it2 = ll_iter_create(card2->providers);2866 2867 struct cc_provider *prov1, *prov2;2868 2869 while ((prov1=ll_iter_next(it1))) {2870 2871 ll_iter_reset(it2);2872 while ((prov2=ll_iter_next(it2))) {2873 if (prov1->prov==prov2->prov) {2874 found++;2875 break;2876 }2877 2878 }2879 }2880 2881 ll_iter_release(it2);2882 ll_iter_release(it1);2883 2884 return found;2885 }2886 2887 /**2888 * equal_providers checks if card1 has exactly the same providers as card22889 * returns 1=equal 0=different2890 **/2891 int equal_providers(struct cc_card *card1, struct cc_card *card2) {2892 2893 if (ll_count(card1->providers) != ll_count(card2->providers))2894 return 0;2895 2896 LL_ITER *it1 = ll_iter_create(card1->providers);2897 LL_ITER *it2 = ll_iter_create(card2->providers);2898 2899 struct cc_provider *prov1, *prov2;2900 2901 while ((prov1=ll_iter_next(it1))) {2902 2903 ll_iter_reset(it2);2904 while ((prov2=ll_iter_next(it2))) {2905 if (prov1->prov==prov2->prov) {2906 break;2907 }2908 2909 }2910 if (!prov2) break;2911 }2912 2913 ll_iter_release(it2);2914 ll_iter_release(it1);2915 2916 return (prov1 == NULL);2917 }2918 2919 /**2920 * Adds a new card to a cardlist.2921 */2922 int add_card_to_serverlist(struct s_reader *rdr, struct s_client *cl, LLIST *cardlist, struct cc_card *card, int reshare, int au_allowed) {2923 2924 if (cfg.cc_minimize_cards == MINIMIZE_TRANSPARENT) {2925 return send_card_to_clients(card, cl);2926 }2927 2928 if (!chk_ident(&cl->ftab, card))2929 return 0;2930 if (rdr && !chk_ident(&rdr->client->ftab, card))2931 return 0;2932 2933 if (!ll_has_elements(card->providers)) { //No providers? Add null-provider:2934 struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);2935 memset(prov, 0, sizeof(struct cc_provider));2936 ll_append(card->providers, prov);2937 }2938 2939 struct cc_data *cc = cl->cc;2940 int modified = 0;2941 LL_ITER *it = ll_iter_create(cardlist);2942 struct cc_card *card2;2943 2944 //Minimize all, transmit just CAID, merge providers:2945 if (cfg.cc_minimize_cards == MINIMIZE_CAID && !cfg.cc_forward_origin_card) {2946 while ((card2 = ll_iter_next(it)))2947 if (card2->caid == card->caid &&2948 !memcmp(card->hexserial, card2->hexserial, sizeof(card->hexserial))) {2949 2950 //Merge cards only if resulting providercount is smaller than CS_MAXPROV2951 int nsame, ndiff, nnew;2952 2953 nsame = num_same_providers(card, card2); //count same cards2954 ndiff = ll_count(card->providers)-nsame; //cound different cards, this cound will be added2955 nnew = ndiff + ll_count(card2->providers); //new card count after add. because its limited to CS_MAXPROV, dont add it2956 2957 if (nnew <= CS_MAXPROV)2958 break;2959 }2960 if (!card2) {2961 card2 = create_card(card);2962 if (!au_allowed)2963 memset(card2->hexserial, 0, 8);2964 card2->hop = 0;2965 card2->remote_id = card->remote_id;2966 card2->maxdown = reshare;2967 ll_clear_data(card2->badsids);2968 ll_iter_insert(it, card2);2969 modified = 1;2970 2971 }2972 else cc->card_dup_count++;2973 2974 add_card_providers(card2, card, 0); //merge all providers2975 2976 }2977 2978 //Removed duplicate cards, keeping card with lower hop:2979 else if (cfg.cc_minimize_cards == MINIMIZE_HOPS && !cfg.cc_forward_origin_card) {2980 while ((card2 = ll_iter_next(it))) {2981 if (card2->caid == card->caid &&2982 !memcmp(card->hexserial, card2->hexserial, sizeof(card->hexserial)) &&2983 equal_providers(card, card2)) {2984 break;2985 }2986 }2987 2988 if (card2 && card2->hop > card->hop) { //hop is smaller, drop old card2989 cc_free_card(card2);2990 ll_iter_remove(it);2991 card2 = NULL;2992 cc->card_dup_count++;2993 }2994 2995 if (!card2) {2996 card2 = create_card(card);2997 if (!au_allowed)2998 memset(card2->hexserial, 0, 8);2999 card2->hop = card->hop;3000 card2->remote_id = card->remote_id;3001 card2->maxdown = reshare;3002 ll_clear_data(card2->badsids);3003 ll_iter_insert(it, card2);3004 add_card_providers(card2, card, 1);3005 modified = 1;3006 }3007 else cc->card_dup_count++;3008 3009 }3010 //like cccam:3011 else { //just remove duplicate cards (same ids)3012 while ((card2 = ll_iter_next(it))) {3013 if (same_card(card, card2))3014 break;3015 }3016 if (card2 && card2->hop > card->hop) {3017 cc_free_card(card2);3018 ll_iter_remove(it);3019 card2 = NULL;3020 cc->card_dup_count++;3021 }3022 if (!card2) {3023 card2 = create_card(card);3024 if (!au_allowed)3025 memset(card2->hexserial, 0, 8);3026 card2->hop = card->hop;3027 card2->remote_id = card->remote_id;3028 card2->maxdown = reshare;3029 card2->origin_reader = rdr;3030 ll_iter_insert(it, card2);3031 add_card_providers(card2, card, 1);3032 modified = 1;3033 }3034 else cc->card_dup_count++;3035 }3036 ll_iter_release(it);3037 return modified;3038 }3039 3040 int find_reported_card(struct s_client * cl, struct cc_card *card1)3041 {3042 struct cc_data *cc = cl->cc;3043 3044 LL_ITER *it = ll_iter_create(cc->reported_carddatas);3045 struct cc_card *card2;3046 while ((card2 = ll_iter_next(it))) {3047 if (same_card(card1, card2)) {3048 card1->id = card2->id; //Set old id !!3049 cc_free_card(card2);3050 ll_iter_remove(it);3051 ll_iter_release(it);3052 return 1; //Old card and new card are equal!3053 }3054 }3055 ll_iter_release(it);3056 return 0; //Card not found3057 }3058 3059 int report_card(struct s_client *cl, struct cc_card *card, LLIST *new_reported_carddatas, int au_allowed)3060 {3061 int res = 0;3062 struct cc_data *cc = cl->cc;3063 int ext = cc->cccam220;3064 if (!find_reported_card(cl, card)) { //Add new card:3065 uint8 *buf = cs_malloc(&buf, CC_MAXMSGSIZE, QUITERROR);3066 if (!cc->report_carddata_id)3067 cc->report_carddata_id = 0x64;3068 card->id = cc->report_carddata_id;3069 cc->report_carddata_id++;3070 3071 int len = write_card(cc, buf, card, TRUE, ext, au_allowed);3072 res = cc_cmd_send(cl, buf, len, ext?MSG_NEW_CARD_SIDINFO:MSG_NEW_CARD);3073 cc->card_added_count++;3074 free(buf);3075 }3076 cc_add_reported_carddata(new_reported_carddatas, card);3077 return res;3078 }3079 3080 void add_good_bad_sids(struct s_sidtab *ptr, struct s_client *cl, struct cc_card *card) {3081 struct cc_data *cc = cl->cc;3082 if (cc->cccam220) {3083 //good sids:3084 int l;3085 for (l=0;l<ptr->num_srvid;l++) {3086 struct cc_srvid *srvid = malloc(sizeof(struct cc_srvid));3087 srvid->sid = ptr->srvid[l];3088 srvid->ecmlen = 0; //0=undefined, also not used with "O" CCcam3089 ll_append(card->goodsids, srvid);3090 }3091 3092 //bad sids:3093 if (cl->sidtabno) {3094 struct s_sidtab *ptr_no;3095 int n;3096 for (n=0,ptr_no=cfg.sidtab; ptr_no; ptr_no=ptr_no->next,n++) {3097 if (cl->sidtabno&((SIDTABBITS)1<<n)) {3098 int m;3099 int ok_caid = FALSE;3100 for (m=0;m<ptr_no->num_caid;m++) { //search bad sids for this caid:3101 if (ptr_no->caid[m] == card->caid) {3102 ok_caid = TRUE;3103 break;3104 }3105 }3106 if (ok_caid) {3107 for (l=0;l<ptr_no->num_srvid;l++) {3108 struct cc_srvid *srvid = malloc(sizeof(struct cc_srvid));3109 srvid->sid = ptr_no->srvid[l];3110 srvid->ecmlen = 0; //0=undefined, also not used with "O" CCcam3111 ll_append(card->badsids, srvid);3112 }3113 }3114 }3115 }3116 }3117 }3118 }3119 3120 void add_good_bad_sids_for_card(struct s_client *cl, struct cc_card *card) {3121 struct cc_data *cc = cl->cc;3122 if (cc->cccam220) {3123 struct s_sidtab *ptr;3124 int j;3125 for (j=0,ptr=cfg.sidtab; ptr; ptr=ptr->next,j++) {3126 if (cl->sidtabok&((SIDTABBITS)1<<j)) {3127 int m;3128 int ok_caid = FALSE;3129 for (m=0;m<ptr->num_caid;m++) { //search good sids for this caid:3130 if (ptr->caid[m] == card->caid) {3131 ok_caid = TRUE;3132 break;3133 }3134 }3135 if (ok_caid) {3136 add_good_bad_sids(ptr, cl, card);3137 }3138 }3139 }3140 }3141 }3142 3143 /**3144 * Server:3145 * Reports all caid/providers to the connected clients3146 * returns 1=ok, 0=error3147 *3148 * cfg.cc_reshare_services=0 CCCAM reader reshares only received cards3149 * =1 CCCAM reader reshares received cards + defined services3150 * =2 CCCAM reader reshares only defined reader-services as virtual cards3151 * =3 CCCAM reader reshares only defined user-services as virtual cards3152 */3153 int cc_srv_report_cards(struct s_client *cl) {3154 int j;3155 uint k;3156 uint8 hop = 0;3157 int reshare, usr_reshare, usr_ignorereshare, reader_reshare, maxhops, flt = 0;3158 3159 struct cc_data *cc = cl->cc;3160 3161 maxhops = cl->account->cccmaxhops;3162 usr_reshare = cl->account->cccreshare;3163 usr_ignorereshare = cl->account->cccignorereshare;3164 3165 LLIST *server_cards = ll_create();3166 if (!cc->reported_carddatas)3167 cc->reported_carddatas = ll_create();3168 LLIST *new_reported_carddatas = ll_create();3169 3170 cc->card_added_count = 0;3171 cc->card_removed_count = 0;3172 cc->card_dup_count = 0;3173 3174 int isau = (ll_count(cl->aureader_list))?1:0;3175 3176 //User-Services:3177 if (cfg.cc_reshare_services==3 && cfg.cc_minimize_cards != MINIMIZE_TRANSPARENT && cfg.sidtab && cl->sidtabok) {3178 struct s_sidtab *ptr;3179 for (j=0,ptr=cfg.sidtab; ptr; ptr=ptr->next,j++) {3180 if (cl->sidtabok&((SIDTABBITS)1<<j)) {3181 int k;3182 for (k=0;k<ptr->num_caid;k++) {3183 struct cc_card *card = create_card2(NULL, (j<<8)|k, ptr->caid[k], hop, usr_reshare);3184 int l;3185 for (l=0;l<ptr->num_provid;l++) {3186 struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);3187 memset(prov, 0, sizeof(struct cc_provider));3188 prov->prov = ptr->provid[l];3189 ll_append(card->providers, prov);3190 }3191 3192 //CCcam 2.2.x proto can transfer good and bad sids:3193 add_good_bad_sids(ptr, cl, card);3194 3195 add_card_to_serverlist(NULL, cl, server_cards, card, usr_reshare, isau);3196 }3197 flt=1;3198 }3199 }3200 }3201 else3202 {3203 struct s_reader *rdr;3204 int r = 0;3205 for (rdr = first_active_reader; rdr; rdr = rdr->next) {3206 if (!rdr->fd)3207 continue;3208 if (!(rdr->grp & cl->grp))3209 continue;3210 reader_reshare = rdr->cc_reshare;3211 3212 reshare = (reader_reshare < usr_reshare) ? reader_reshare : usr_reshare;3213 if (reshare < 0)3214 continue;3215 3216 //Generate a uniq reader id:3217 if (!rdr->cc_id) {3218 rdr->cc_id = ++r;3219 struct s_reader *rdr2;3220 for (rdr2 = first_active_reader; rdr2; rdr2 = rdr2->next) {3221 if (rdr2 != rdr && rdr2->cc_id == rdr->cc_id) {3222 rdr2 = first_active_reader;3223 rdr->cc_id=++r;3224 }3225 }3226 }3227 3228 isau = ll_contains(cl->aureader_list, rdr);3229 int au_allowed = !rdr->audisabled && isau;3230 3231 flt = 0;3232 3233 //Reader-Services:3234 if ((cfg.cc_reshare_services==1||cfg.cc_reshare_services==2) && cfg.sidtab && rdr->sidtabok) {3235 struct s_sidtab *ptr;3236 for (j=0,ptr=cfg.sidtab; ptr; ptr=ptr->next,j++) {3237 if (rdr->sidtabok&((SIDTABBITS)1<<j)) {3238 int k;3239 for (k=0;k<ptr->num_caid;k++) {3240 struct cc_card *card = create_card2(rdr, (j<<8)|k, ptr->caid[k], hop, reshare);3241 int l;3242 for (l=0;l<ptr->num_provid;l++) {3243 struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);3244 memset(prov, 0, sizeof(struct cc_provider));3245 prov->prov = ptr->provid[l];3246 ll_append(card->providers, prov);3247 }3248 3249 //CCcam 2.2.x proto can transfer good and bad sids:3250 add_good_bad_sids(ptr, cl, card);3251 3252 add_card_to_serverlist(rdr, cl, server_cards, card, reshare, au_allowed);3253 }3254 flt=1;3255 }3256 }3257 }3258 3259 //Filts by Hardware readers:3260 if ((rdr->typ != R_CCCAM) && rdr->ftab.filts && !flt) {3261 for (j = 0; j < CS_MAXFILTERS; j++) {3262 if (rdr->ftab.filts[j].caid &&3263 chk_ctab(rdr->ftab.filts[j].caid, &cl->ctab)) {3264 int ignore = 0;3265 ushort caid = rdr->ftab.filts[j].caid;3266 struct cc_card *card = create_card2(rdr, j, caid, hop, reshare);3267 //Setting UA: (Unique Address):3268 if (au_allowed)3269 cc_UA_oscam2cccam(rdr->hexserial, card->hexserial, caid);3270 //cs_log("Ident CCcam card report caid: %04X readr %s subid: %06X", rdr->ftab.filts[j].caid, rdr->label, rdr->cc_id);3271 for (k = 0; k < rdr->ftab.filts[j].nprids; k++) {3272 struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);3273 memset(prov, 0, sizeof(struct cc_provider));3274 prov->prov = rdr->ftab.filts[j].prids[k];3275 3276 if (!chk_srvid_by_caid_prov(cl, caid, prov->prov)) {3277 ignore = 1;3278 }3279 //cs_log("Ident CCcam card report provider: %02X%02X%02X", buf[21 + (k*7)]<<16, buf[22 + (k*7)], buf[23 + (k*7)]);3280 if (au_allowed) {3281 int l;3282 for (l = 0; l < rdr->nprov; l++) {3283 ulong rprid = get_reader_prid(rdr, l);3284 if (rprid == prov->prov)3285 cc_SA_oscam2cccam(&rdr->sa[l][0], prov->sa);3286 }3287 }3288 3289 ll_append(card->providers, prov);3290 }3291 3292 //check remote node id, do not send if this card is from there:3293 if (!ignore) {3294 LL_ITER *it = ll_iter_create(card->remote_nodes);3295 uint8 * node;3296 while (!ignore && (node=ll_iter_next(it))) {3297 if (!memcmp(node, cc->peer_node_id, 8))3298 ignore = TRUE;3299 }3300 ll_iter_release(it);3301 }3302 3303 if (!ignore) {3304 //CCcam 2.2.x proto can transfer good and bad sids:3305 add_good_bad_sids_for_card(cl, card);3306 3307 add_card_to_serverlist(rdr, cl, server_cards, card, reshare, au_allowed);3308 }3309 else cc_free_card(card);3310 flt = 1;3311 }3312 }3313 }3314 3315 if ((rdr->typ != R_CCCAM) && !rdr->caid && !flt) {3316 for (j = 0; j < CS_MAXCAIDTAB; j++) {3317 //cs_log("CAID map CCcam card report caid: %04X cmap: %04X", rdr->ctab.caid[j], rdr->ctab.cmap[j]);3318 ushort lcaid = rdr->ctab.caid[j];3319 3320 if (!lcaid || (lcaid == 0xFFFF))3321 lcaid = rdr->ctab.cmap[j];3322 3323 if (lcaid && (lcaid != 0xFFFF) && chk_ctab(lcaid, &cl->ctab)) {3324 struct cc_card *card = create_card2(rdr, j, lcaid, hop, reshare);3325 if (au_allowed)3326 cc_UA_oscam2cccam(rdr->hexserial, card->hexserial, lcaid);3327 3328 //CCcam 2.2.x proto can transfer good and bad sids:3329 add_good_bad_sids_for_card(cl, card);3330 3331 add_card_to_serverlist(rdr, cl, server_cards, card, reshare, au_allowed);3332 flt = 1;3333 }3334 }3335 }3336 3337 if ((rdr->typ != R_CCCAM) && rdr->caid && !flt && chk_ctab(rdr->caid, &cl->ctab)) {3338 //cs_log("tcp_connected: %d card_status: %d ", rdr->tcp_connected, rdr->card_status);3339 ushort caid = rdr->caid;3340 struct cc_card *card = create_card2(rdr, 0, caid, hop, reshare);3341 if (au_allowed)3342 cc_UA_oscam2cccam(rdr->hexserial, card->hexserial, caid);3343 for (j = 0; j < rdr->nprov; j++) {3344 ulong prid = get_reader_prid(rdr, j);3345 struct cc_provider *prov = cs_malloc(&prov, sizeof(struct cc_provider), QUITERROR);3346 memset(prov, 0, sizeof(struct cc_provider));3347 prov->prov = prid;3348 //cs_log("Ident CCcam card report provider: %02X%02X%02X", buf[21 + (k*7)]<<16, buf[22 + (k*7)], buf[23 + (k*7)]);3349 if (au_allowed) {3350 //Setting SA (Shared Addresses):3351 cc_SA_oscam2cccam(rdr->sa[j], prov->sa);3352 }3353 ll_append(card->providers, prov);3354 //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)]);3355 }3356 if (rdr->tcp_connected || rdr->card_status == CARD_INSERTED) {3357 3358 //CCcam 2.2.x proto can transfer good and bad sids:3359 add_good_bad_sids_for_card(cl, card);3360 3361 add_card_to_serverlist(rdr, cl, server_cards, card, reshare, au_allowed);3362 }3363 else3364 cc_free_card(card);3365 }3366 3367 if (rdr->typ == R_CCCAM && cfg.cc_reshare_services<2 && rdr->card_status != CARD_FAILURE) {3368 3369 cs_debug_mask(D_CLIENT, "%s asking reader %s for cards...",3370 getprefix(), rdr->label);3371 3372 struct cc_card *card;3373 struct s_client *rc = rdr->client;3374 struct cc_data *rcc = rc?rc->cc:NULL;3375 3376 int count = 0;3377 if (rcc && rcc->cards && rcc->mode == CCCAM_MODE_NORMAL) {3378 if (!pthread_mutex_trylock(&rcc->cards_busy)) {3379 LL_ITER *it = ll_iter_create(rcc->cards);3380 while ((card = ll_iter_next(it))) {3381 if (card->hop <= maxhops && chk_ctab(card->caid, &cl->ctab)3382 && chk_ctab(card->caid, &rdr->ctab)) {3383 3384 if ((cfg.cc_ignore_reshare || usr_ignorereshare || card->maxdown > 0)) {3385 int ignore = 0;3386 3387 LL_ITER *it2 = ll_iter_create(card->providers);3388 struct cc_provider *prov;3389 while ((prov = ll_iter_next(it2))) {3390 ulong prid = prov->prov;3391 if (!chk_srvid_by_caid_prov(cl, card->caid,3392 prid) || !chk_srvid_by_caid_prov(3393 rdr->client, card->caid, prid)) {3394 ignore = 1;3395 break;3396 }3397 }3398 ll_iter_release(it2);3399 3400 if (!ignore) { //Filtered by service3401 int new_reshare =3402 ( cfg.cc_ignore_reshare || usr_ignorereshare ) ? reshare3403 : (card->maxdown - 1);3404 if (new_reshare > reshare)3405 new_reshare = reshare;3406 add_card_to_serverlist(rdr, cl, server_cards, card,3407 new_reshare, au_allowed);3408 count++;3409 }3410 }3411 }3412 }3413 ll_iter_release(it);3414 pthread_mutex_unlock(&rcc->cards_busy);3415 }3416 }3417 cs_debug_mask(D_CLIENT, "%s got %d cards from %s", getprefix(),3418 count, rdr->label);3419 }3420 }3421 }3422 3423 int ok = TRUE;3424 if (cfg.cc_minimize_cards == MINIMIZE_TRANSPARENT) { //add_to_server_list alread reported the cards!3425 //so just clean up:3426 cc_free_cardlist(server_cards, TRUE);3427 cc_free_cardlist(new_reported_carddatas, TRUE);3428 }3429 else {3430 //report reshare cards:3431 //cs_debug_mask(D_TRACE, "%s reporting %d cards", getprefix(), ll_count(server_cards));3432 LL_ITER *it = ll_iter_create(server_cards);3433 struct cc_card *card;3434 while (ok && (card = ll_iter_next(it))) {3435 //cs_debug_mask(D_TRACE, "%s card %d caid %04X hop %d", getprefix(), card->id, card->caid, card->hop);3436 3437 ok = report_card(cl, card, new_reported_carddatas, isau) >= 0;3438 ll_iter_remove(it);3439 }3440 ll_iter_release(it);3441 cc_free_cardlist(server_cards, TRUE);3442 3443 //remove unsed, remaining cards:3444 cc->card_removed_count += cc_free_reported_carddata(cl, cc->reported_carddatas, new_reported_carddatas, ok);3445 cc->reported_carddatas = new_reported_carddatas;3446 3447 cs_debug_mask(D_CLIENT, "%s reported/updated +%d/-%d/dup %d of %d cards to client (ext=%d)", getprefix(),3448 cc->card_added_count, cc->card_removed_count, cc->card_dup_count, ll_count(cc->reported_carddatas), cc->cccam220);3449 }3450 return ok;3451 }3452 3453 2430 void cc_init_cc(struct cc_data *cc) { 3454 2431 pthread_mutex_init(&cc->lock, NULL); //No recursive lock … … 3481 2458 } 3482 2459 3483 int cc_cards_modified() {3484 int modified = 0;3485 struct s_reader *rdr;3486 for (rdr = first_active_reader; rdr; rdr = rdr->next) {3487 if (rdr->typ == R_CCCAM && rdr->fd) {3488 struct s_client *clr = rdr->client;3489 if (clr && clr->cc) {3490 struct cc_data *ccr = clr->cc;3491 modified += ccr->cards_modified;3492 }3493 }3494 }3495 return modified;3496 }3497 2460 3498 2461 int check_cccam_compat(struct cc_data *cc) { … … 3530 2493 cc_init_cc(cc); 3531 2494 } 2495 cc->mode = CCCAM_MODE_NOTINIT; 3532 2496 cc->server_ecm_pending = 0; 3533 2497 cc->extended_mode = 0; … … 3687 2651 3688 2652 // report cards 3689 ulong hexserial_crc = get_reader_hexserial_crc(cl);3690 3691 2653 if (wakeup > 0) //give readers time to get cards: 3692 2654 cs_sleepms(500); … … 3698 2660 cmi = 0; 3699 2661 wait_for_keepalive = 100; 2662 cc->mode = CCCAM_MODE_NORMAL; 3700 2663 //some clients, e.g. mgcamd, does not support keepalive. So if not answered, keep connection 3701 2664 // check for client timeout, if timeout occurs try to send keepalive … … 3733 2696 break; //mode wrong or duplicate user -->disconect 3734 2697 3735 if (!cc->server_ecm_pending) {3736 struct timeb timeout;3737 struct timeb cur_time;3738 cs_ftime(&cur_time);3739 timeout = cc->ecm_time;3740 timeout.time += cfg.cc_update_interval;3741 3742 int needs_card_updates = (cfg.cc_update_interval >= 0)3743 && comp_timeb(&cur_time, &timeout) > 0;3744 3745 if (needs_card_updates || !cc->cards_modified) {3746 cc->ecm_time = cur_time;3747 ulong new_hexserial_crc = get_reader_hexserial_crc(cl);3748 int cards_modified = cc_cards_modified();3749 if (new_hexserial_crc != hexserial_crc || cards_modified3750 != cc->cards_modified) {3751 cs_debug_mask(D_CLIENT, "%s update share list",3752 getprefix());3753 3754 hexserial_crc = new_hexserial_crc;3755 cc->cards_modified = cards_modified;3756 3757 if (!cc_srv_report_cards(cl))3758 return -1;3759 }3760 }3761 }3762 2698 } 3763 2699 … … 3789 2725 rdr->card_status = CARD_FAILURE; 3790 2726 3791 if (cc && cc->mode != CCCAM_MODE_NO RMAL)2727 if (cc && cc->mode != CCCAM_MODE_NOTINIT) 3792 2728 return -99; 3793 2729 … … 3965 2901 3966 2902 cc->just_logged_in = 1; 2903 cc->mode = CCCAM_MODE_NORMAL; 3967 2904 cl->crypted = 1; 3968 2905 … … 4162 3099 cc_node_id[6] = sum >> 8; 4163 3100 cc_node_id[7] = sum & 0xff; 4164 } 3101 3102 init_share(); 3103 }
Note:
See TracChangeset
for help on using the changeset viewer.