Changeset 18690


Ignore:
Timestamp:
11/21/12 21:13:33 (11 years ago)
Author:
nit
Message:

[titan] update ca system

Location:
titan/titan
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • titan/titan/ca.h

    r18526 r18690  
    17151715}
    17161716
    1717 int sendcapmttocam(struct service* node, unsigned char* buf, int len, int caservicenr, int cmdpos, int clear)
     1717int sendcapmttocam(struct dvbdev* dvbnode, struct service* node, unsigned char* buf, int len, int caservicenr, int cmdpos, int clear)
    17181718{
    17191719        int i = 0;
    17201720        char* tmpstr = NULL, *blacklist = NULL;
    1721         struct dvbdev *dvbnode = dvbdev;
    1722 
    1723         if(node == NULL) return 0;
    1724 
    1725         while(dvbnode != NULL)
    1726         {
    1727                 if(dvbnode->type == CIDEV && dvbnode->fd > -1 && dvbnode->caslot != NULL && dvbnode->caslot->status == 2 && dvbnode->caslot->caids != NULL)
    1728                 {
    1729                         //send clear only to right cimodule
    1730                         if(clear > 0 && caservice[clear - 1].caslot != dvbnode->caslot)
    1731                         {
    1732                                 dvbnode = dvbnode->next;
    1733                                 continue;
    1734                         }
    1735 
    1736                         //check if crypt can onyl handle single service
    1737                         tmpstr = ostrcat("camtype_", oitoa(dvbnode->devnr), 0, 1);
    1738                         if(clear == 0 && getconfigint(tmpstr, NULL) == 0 && getcaservicebyslot(dvbnode->caslot, 1) > -1)
    1739                         {
    1740                                 debug(620, "cam is singel and is in use");
     1721
     1722        if(node == NULL && dvbnode == NULL) return 1;
     1723
     1724        if(dvbnode->type == CIDEV && dvbnode->fd > -1 && dvbnode->caslot != NULL && dvbnode->caslot->status == 2 && dvbnode->caslot->caids != NULL)
     1725        {
     1726                //check if crypt can onyl handle single service
     1727                tmpstr = ostrcat("camtype_", oitoa(dvbnode->devnr), 0, 1);
     1728                if(clear == 0 && getconfigint(tmpstr, NULL) == 0 && getcaservicebyslot(dvbnode->caslot, 1) > -1)
     1729                {
     1730                        debug(620, "cam is singel and is in use");
     1731                        free(tmpstr); tmpstr = NULL;
     1732                        return 1;
     1733                }
     1734                free(tmpstr); tmpstr = NULL;
     1735
     1736                //check if cam can caid
     1737                int foundcaid = 0;
     1738                tmpstr = ostrcat("camblacklist_", oitoa(dvbnode->devnr), 0, 1);
     1739                blacklist = getconfig(tmpstr, NULL);
     1740                free(tmpstr); tmpstr = NULL;
     1741                if(node->channel != NULL)
     1742                {
     1743                        struct cadesc *nodecadesc = node->channel->cadesc;
     1744                        while(nodecadesc != NULL)
     1745                        {
     1746                                debug(620, "cam-ciads=%s", dvbnode->caslot->caids);
     1747                                debug(620, "videopid=%d, audiopid=%d, ac3pid=%d, capid=%d, caid=%d", node->channel->videopid, node->channel->audiopid, node->channel->ac3audiopid, nodecadesc->pid, nodecadesc->systemid);
     1748                                tmpstr = oitoa(nodecadesc->systemid);
     1749                                if(ostrstr(dvbnode->caslot->caids, tmpstr) != NULL)
     1750                                {
     1751                                        //check if caid is in cams blacklist
     1752                                        if(blacklist == NULL || ostrstr(blacklist, tmpstr) == NULL)
     1753                                        {
     1754                                                foundcaid = 1;
     1755                                                break;
     1756                                        }
     1757                                        else
     1758                                                debug(620, "caid is in blacklist (%s -> %s)", tmpstr, blacklist);
     1759                                }
    17411760                                free(tmpstr); tmpstr = NULL;
    1742                                 dvbnode = dvbnode->next;
    1743                                 continue;
    1744                         }
    1745                         free(tmpstr); tmpstr = NULL;
    1746 
    1747                         //check if cam can caid
    1748                         int foundcaid = 0;
    1749                         tmpstr = ostrcat("camblacklist_", oitoa(dvbnode->devnr), 0, 1);
    1750                         blacklist = getconfig(tmpstr, NULL);
    1751                         free(tmpstr); tmpstr = NULL;
    1752                         if(node->channel != NULL)
    1753                         {
    1754                                 struct cadesc *nodecadesc = node->channel->cadesc;
    1755                                 while(nodecadesc != NULL)
    1756                                 {
    1757                                         debug(620, "cam-ciads=%s", dvbnode->caslot->caids);
    1758                                         debug(620, "videopid=%d, audiopid=%d, ac3pid=%d, capid=%d, caid=%d", node->channel->videopid, node->channel->audiopid, node->channel->ac3audiopid, nodecadesc->pid, nodecadesc->systemid);
    1759                                         tmpstr = oitoa(nodecadesc->systemid);
    1760                                         if(ostrstr(dvbnode->caslot->caids, tmpstr) != NULL)
    1761                                         {
    1762                                                 //check if caid is in cams blacklist
    1763                                                 if(blacklist == NULL || ostrstr(blacklist, tmpstr) == NULL)
    1764                                                 {
    1765                                                         foundcaid = 1;
    1766                                                         break;
    1767                                                 }
    1768                                                 else
    1769                                                         debug(620, "caid is in blacklist (%s -> %s)", tmpstr, blacklist);
    1770                                         }
    1771                                         free(tmpstr); tmpstr = NULL;
    1772 
    1773                                         nodecadesc = nodecadesc->next;
    1774                                 }
    1775                         }
    1776                         free(tmpstr); tmpstr = NULL;
    1777 
    1778                         if(foundcaid == 0)
    1779                         {
    1780                                 debug(620, "cam not supports caid");
    1781                                 dvbnode = dvbnode->next;
    1782                                 continue;
    1783                         }
    1784 
    1785                         //check if we can change input sources
     1761                nodecadesc = nodecadesc->next;
     1762                        }
     1763                }
     1764                free(tmpstr); tmpstr = NULL;
     1765
     1766                if(foundcaid == 0)
     1767                {
     1768                        debug(620, "cam not supports caid");
     1769                        return 1;
     1770                }
     1771
     1772                //check if we can change input sources
     1773                for(i = 0; i < MAXCASERVICE; i++)
     1774                {
     1775                        if(caservice[i].caslot != NULL && caservice[i].service != NULL && caservice[i].service->fedev != NULL && node->fedev != NULL)
     1776                        {
     1777                                if(caservice[i].caslot == dvbnode->caslot && caservice[i].service->fedev->devnr != node->fedev->devnr && (caservice[i].service->type == RECORDDIRECT || caservice[i].service->type == RECORDTIMER))
     1778                                {
     1779                                        debug(620, "can't change input sources");
     1780                                        return 1;
     1781                                }
     1782                        }
     1783                }
     1784
     1785                //got free camanager
     1786                if(caservice[caservicenr].camanager == -1)
     1787                {
     1788                        caservice[caservicenr].camanager = getfreecasession(dvbnode, 2, 1);
     1789                        debug(620, "use camanager %d", caservice[caservicenr].camanager);
     1790                }
     1791
     1792                //check if cam can decrypt
     1793                if(clear == 0 && caservice[caservicenr].camanager > -1 && getconfigint("checkcamdecrypt", NULL) == 1)
     1794                {
     1795                        if(buf != NULL && len >= cmdpos)
     1796                        {
     1797                                status.checkcamdecrypt = 100;
     1798                                buf[cmdpos] = 0x03;
     1799                                buf[cmdpos - 6] = 0x04; //WA for alphacrypt, only delete all ca-pmt
     1800                                sendSPDU(dvbnode, 0x90, NULL, 0, caservice[caservicenr].camanager, buf, len);
     1801                                buf[cmdpos] = 0x01;
     1802                                buf[cmdpos - 6] = 0x03;
     1803                                while(status.checkcamdecrypt > 0)
     1804                                {
     1805                                        status.checkcamdecrypt--;
     1806                                        usleep(30000);
     1807                                }
     1808                if(status.checkcamdecrypt == -2)
     1809                                {
     1810                                        dvbnode->caslot->casession[caservice[caservicenr].camanager].inuse = 1;
     1811                                        caservice[caservicenr].camanager = -1;
     1812                                }
     1813                        }
     1814                }
     1815
     1816                //decrypt
     1817                if(caservice[caservicenr].camanager > -1)
     1818                {
     1819                        //change ciX_input and inputX
     1820                        if(clear == 0 && node->fedev != NULL)
     1821                        {
     1822                                char* ci = NULL;
     1823                                debug(620, "set ci slot %d to tuner %d", dvbnode->devnr, node->fedev->devnr);
     1824                                switch(node->fedev->devnr)
     1825                                {
     1826                                        case 0:
     1827                                                setciinput(dvbnode->devnr, "A");
     1828                                                ci = ostrcat("CI", oitoa(dvbnode->devnr), 0, 1);
     1829                                                setcisource(node->fedev->devnr, ci);
     1830                                                free(ci); ci = NULL;
     1831                                                break;
     1832                                        case 1:
     1833                                                setciinput(dvbnode->devnr, "B");
     1834                                                ci = ostrcat("CI", oitoa(dvbnode->devnr), 0, 1);
     1835                                                setcisource(node->fedev->devnr, ci);
     1836                                                free(ci); ci = NULL;
     1837                                                break;
     1838                                        case 2:
     1839                                                setciinput(dvbnode->devnr, "C");
     1840                                                ci = ostrcat("CI", oitoa(dvbnode->devnr), 0, 1);
     1841                                                setcisource(node->fedev->devnr, ci);
     1842                                                free(ci); ci = NULL;
     1843                                                break;
     1844                                        case 3:
     1845                                                setciinput(dvbnode->devnr, "D");
     1846                                                ci = ostrcat("CI", oitoa(dvbnode->devnr), 0, 1);
     1847                                                setcisource(node->fedev->devnr, ci);
     1848                                                free(ci); ci = NULL;
     1849                                                break;
     1850                                }
     1851                        }
     1852                        //send all saved capmt first
     1853                        int first = 0;
    17861854                        for(i = 0; i < MAXCASERVICE; i++)
    17871855                        {
    1788                                 if(caservice[i].caslot != NULL && caservice[i].service != NULL && caservice[i].service->fedev != NULL && node->fedev != NULL)
    1789                                 {
    1790                                         if(caservice[i].caslot == dvbnode->caslot && caservice[i].service->fedev->devnr != node->fedev->devnr && (caservice[i].service->type == RECORDDIRECT || caservice[i].service->type == RECORDTIMER))
    1791                                         {
    1792                                                 debug(620, "can't change input sources");
    1793                                                 dvbnode = dvbnode->next;
    1794                                                 continue;
    1795                                         }
    1796                                 }
    1797                         }
    1798 
    1799                         //got free camanager
    1800                         if(caservice[caservicenr].camanager == -1)
    1801                         {
    1802                                 caservice[caservicenr].camanager = getfreecasession(dvbnode, 2, 1);
    1803                                 debug(620, "use camanager %d", caservice[caservicenr].camanager);
    1804                         }
    1805 
    1806                         //check if cam can decrypt
    1807                         if(clear == 0 && caservice[caservicenr].camanager > -1 && getconfigint("checkcamdecrypt", NULL) == 1)
    1808                         {
    1809                                 if(buf != NULL && len >= cmdpos)
    1810                                 {
    1811                                         status.checkcamdecrypt = 100;
    1812                                         buf[cmdpos] = 0x03;
    1813                                         buf[cmdpos - 6] = 0x04; //WA for alphacrypt, only delete all ca-pmt
    1814                                         sendSPDU(dvbnode, 0x90, NULL, 0, caservice[caservicenr].camanager, buf, len);
    1815                                         buf[cmdpos] = 0x01;
    1816                                         buf[cmdpos - 6] = 0x03;
    1817                                         while(status.checkcamdecrypt > 0)
    1818                                         {
    1819                                                 status.checkcamdecrypt--;
    1820                                                 usleep(30000);
    1821                                         }
    1822 
    1823                                         if(status.checkcamdecrypt == -2)
    1824                                         {
    1825                                                 dvbnode->caslot->casession[caservice[caservicenr].camanager].inuse = 1;
    1826                                                 caservice[caservicenr].camanager = -1;
    1827                                         }
    1828                                 }
    1829                         }
    1830 
    1831                         //decrypt
    1832                         if(caservice[caservicenr].camanager > -1)
    1833                         {
    1834                                 //change ciX_input and inputX
    1835                                 if(clear == 0 && node->fedev != NULL)
    1836                                 {
    1837                                         char* ci = NULL;
    1838                                         debug(620, "set ci slot %d to tuner %d", dvbnode->devnr, node->fedev->devnr);
    1839                                         switch(node->fedev->devnr)
    1840                                         {
    1841                                                 case 0:
    1842                                                         setciinput(dvbnode->devnr, "A");
    1843                                                         ci = ostrcat("CI", oitoa(dvbnode->devnr), 0, 1);
    1844                                                         setcisource(node->fedev->devnr, ci);
    1845                                                         free(ci); ci = NULL;
    1846                                                         break;
    1847                                                 case 1:
    1848                                                         setciinput(dvbnode->devnr, "B");
    1849                                                         ci = ostrcat("CI", oitoa(dvbnode->devnr), 0, 1);
    1850                                                         setcisource(node->fedev->devnr, ci);
    1851                                                         free(ci); ci = NULL;
    1852                                                         break;
    1853                                                 case 2:
    1854                                                         setciinput(dvbnode->devnr, "C");
    1855                                                         ci = ostrcat("CI", oitoa(dvbnode->devnr), 0, 1);
    1856                                                         setcisource(node->fedev->devnr, ci);
    1857                                                         free(ci); ci = NULL;
    1858                                                         break;
    1859                                                 case 3:
    1860                                                         setciinput(dvbnode->devnr, "D");
    1861                                                         ci = ostrcat("CI", oitoa(dvbnode->devnr), 0, 1);
    1862                                                         setcisource(node->fedev->devnr, ci);
    1863                                                         free(ci); ci = NULL;
    1864                                                         break;
    1865                                         }
    1866                                 }
    1867                                 //send all saved capmt first
    1868                                 int first = 0;
    1869                                 for(i = 0; i < MAXCASERVICE; i++)
    1870                                 {
    1871                                         if(dvbnode->caslot == caservice[i].caslot && caservice[i].capmt != NULL && caservice[i].capmtlen > 0)
    1872                                         {
    1873                                                 if(i == 0)
    1874                                                         caservice[i].capmt[caservice[i].cmdpos - 6] = 0x01;
    1875                                                 else
    1876                                                         caservice[i].capmt[caservice[i].cmdpos - 6] = 0x00;
    1877                                                 first = 1;
    1878                                                 sendSPDU(dvbnode, 0x90, NULL, 0, caservice[i].camanager, caservice[i].capmt, caservice[i].capmtlen);
    1879                                         }
    1880                                 }
    1881                                 //send new capmt
    1882                                 if(first == 1) buf[cmdpos - 6] = 0x02;
    1883                                 sendSPDU(dvbnode, 0x90, NULL, 0, caservice[caservicenr].camanager, buf, len);
    1884                                 caservice[caservicenr].caslot = dvbnode->caslot;
    1885                                 //save new capmt
    1886                                 char* tmpbuf = malloc(len);
    1887                                 if(tmpbuf != NULL)
    1888                                 {
    1889                                         memcpy(tmpbuf, buf, len);
    1890                                         free(caservice[caservicenr].capmt);
    1891                                         caservice[caservicenr].capmt = tmpbuf;
    1892                                         caservice[caservicenr].capmtlen = len;
    1893                                         caservice[caservicenr].cmdpos = cmdpos;
    1894                                 }
    1895                                 debug(620, "found cam for decrypt (slot=%d)", dvbnode->devnr);
    1896                                 break;
    1897                         }
    1898                         else
    1899                                 debug(620, "no free camanager found");
    1900                 }
    1901                 dvbnode = dvbnode->next;
     1856                                if(dvbnode->caslot == caservice[i].caslot && caservice[i].capmt != NULL && caservice[i].capmtlen > 0)
     1857                                {
     1858                                        if(i == 0)
     1859                                                caservice[i].capmt[caservice[i].cmdpos - 6] = 0x01;
     1860                                        else
     1861                                                caservice[i].capmt[caservice[i].cmdpos - 6] = 0x00;
     1862                                        first = 1;
     1863                                        sendSPDU(dvbnode, 0x90, NULL, 0, caservice[i].camanager, caservice[i].capmt, caservice[i].capmtlen);
     1864                                }
     1865                        }
     1866                        //send new capmt
     1867                        if(first == 1) buf[cmdpos - 6] = 0x02;
     1868                        sendSPDU(dvbnode, 0x90, NULL, 0, caservice[caservicenr].camanager, buf, len);
     1869                        caservice[caservicenr].caslot = dvbnode->caslot;
     1870                        //save new capmt
     1871                        char* tmpbuf = malloc(len);
     1872                        if(tmpbuf != NULL)
     1873                        {
     1874                                memcpy(tmpbuf, buf, len);
     1875                                free(caservice[caservicenr].capmt);
     1876                                caservice[caservicenr].capmt = tmpbuf;
     1877                                caservice[caservicenr].capmtlen = len;
     1878                                caservice[caservicenr].cmdpos = cmdpos;
     1879                        }
     1880                        debug(620, "found cam for decrypt (slot=%d)", dvbnode->devnr);
     1881                        return 0;
     1882                }
     1883                else
     1884                        debug(620, "no free camanager found");
    19021885        }
    19031886        return 1;
  • titan/titan/cam.h

    r18666 r18690  
    207207}
    208208
    209 //flag 0 = from zap
    210 //flag 1 = from watchthread
    211 //flag 2 = from cathread / caservicedel
    212 //flag 3 = from recordthread
    213 void sendcapmt(struct service* node, int clear, int flag)
    214 {
    215         int pos = 10, i = 0, lenbytes = 0, round = 0, caservicenr = 0;
    216         unsigned char* buf = NULL;
    217 
    218         //check if service should decrypt
    219         if(node == NULL)
    220         {
    221                 debug(620, "service empty");
    222                 return;
    223         }
    224         if(node->channel == NULL)
    225         {
    226                 debug(620, "channel empty");
    227                 return;
    228         }
    229         if(node->fedev == NULL)
    230         {
    231                 debug(620, "no frontend");
    232                 return;
    233         }
    234        
    235         if(node->channel->crypt == 0)
    236         {
    237                 debug(620, "channel not crypt");
    238 
    239                 //check if we can change input sources
    240                 int doswitch = 1;
    241                 for(i = 0; i < MAXCASERVICE; i++)
    242                 {
    243                         if(caservice[i].caslot != NULL && caservice[i].service != NULL && caservice[i].service->fedev != NULL)
    244                         {
    245                                 if(caservice[i].service->fedev->devnr == node->fedev->devnr && (caservice[i].service->type == RECORDDIRECT || caservice[i].service->type == RECORDTIMER))
    246                                 {
    247                                         debug(620, "can't change input sources");
    248                                         doswitch = 0;
    249                                 }
    250                         }
    251                 }
    252 
    253                 if(doswitch == 1)
    254                 {
    255                         debug(200, "reset routing tuner %d", node->fedev->devnr);
    256                         switch(node->fedev->devnr)
    257                         {
    258                                 case 0: setcisource(node->fedev->devnr, "A"); break;
    259                                 case 1: setcisource(node->fedev->devnr, "B"); break;
    260                                 case 2: setcisource(node->fedev->devnr, "C"); break;
    261                                 case 3: setcisource(node->fedev->devnr, "D"); break;
    262                         }
    263                 }
    264                
    265                 return;
    266         }
    267        
    268         if(node->channel->pmt == NULL)
    269         {
    270                 debug(620, "pmt empty");
    271                 return;
    272         }
    273         if(node->channel->cadesc == NULL)
    274         {
    275                 debug(620, "cadesc empty");
    276                 return;
    277         }
    278         if(node->channel->esinfo == NULL)
    279         {
    280                 debug(620, "esinfo empty");
    281                 return;
    282         }
    283         if(node->fedev->type == FRONTENDDEVDUMMY)
    284         {
    285                 debug(620, "dummy frontend not crypt");
    286                 return;
    287         }
    288         if(flag != 3 && node->type != CHANNEL && node->type != RECORDDIRECT && node->type != RECORDTIMER && node->type != RECORDTIMESHIFT && node->type != RECORDSTREAM)
    289         {
    290                 debug(620, "service type should not decrypt");
    291                 return;
    292         }
    293 
    294         buf = malloc(MINMALLOC);
    295         if(buf == NULL)
    296         {
    297                 err("no mem");
    298                 return;
    299         }
    300 
    301         if(clear == 0)
    302         {
    303                 caservicenr = caserviceadd(node, flag);
    304                 if(caservicenr < 0)
    305                 {
    306                         debug(620, "service is decrypt");
    307                         free(buf);
    308                         return;
    309                 }
    310         }
    311 
     209//flag 0: cam capmt
     210//flag 1: emu capmt
     211//flag 2: clear capmt
     212int createcapmt(struct dvbdev* dvbnode, struct service* node, unsigned char* buf, int* lenbytes, int flag)
     213{
     214        if(buf == NULL || node == NULL || node->channel == NULL) return -1;
     215        if(node->fedev == NULL || node->channel->pmt == NULL) return -1;
     216        if(node->channel->cadesc == NULL || node->channel->esinfo == NULL) return -1;
     217
     218        int pos = 10, i = 0;
    312219        struct cadesc* cadescnode = node->channel->cadesc;
    313220        struct esinfo* esinfonode = node->channel->esinfo;
    314221
    315 start:
    316         pos = 10, lenbytes = 0, i = 0;
    317         cadescnode = node->channel->cadesc;
    318         esinfonode = node->channel->esinfo;
    319222        memset(buf, 0, MINMALLOC);
    320223
     
    329232        buf[pos++] = (node->channel->pmt->versionnumber << 1) | node->channel->pmt->currentnextindicator;
    330233
    331         buf[pos++] = 0x00; //len from here (programinfo len) 
     234        buf[pos++] = 0x00; //len from here (programinfo len)
    332235        buf[pos++] = 0x00; //len from here (programinfo len)
    333236        buf[pos++] = 0x01; //ca_pmt_cmd_id: ok_descrambling=1
    334237
    335         if(round == 1)
     238        if(flag == 1)
    336239        {
    337240                buf[pos++] = 0x81; //id (fix)
     
    370273        }
    371274
    372         while(cadescnode != NULL && clear == 0)
    373         {
    374 
     275        while(cadescnode != NULL && flag < 2)
     276        {
    375277                //remove caids, cam can't
    376                 if(round == 0 && status.casendallcaids == 0)
    377                 {
    378                         int treffer = 0;
    379                         struct dvbdev* dvbnode = dvbdev;
     278                if(flag == 0 && status.casendallcaids == 0)
     279                {
    380280                        char* tmpnr = NULL;
    381281
    382                         while(dvbnode != NULL)
    383                         {
    384                                 if(dvbnode->type == CIDEV && dvbnode->fd > -1 && dvbnode->caslot != NULL && dvbnode->caslot->status == 2 && dvbnode->caslot->caids != NULL)
     282                        if(dvbnode != NULL)
     283                        {
     284                                tmpnr = oitoa(cadescnode->systemid);
     285                                if(ostrstr(dvbnode->caslot->caids, tmpnr) == NULL)
    385286                                {
    386                                         tmpnr = oitoa(cadescnode->systemid);
    387                                         if(ostrstr(dvbnode->caslot->caids, tmpnr) != NULL)
    388                                         {
    389                                                 free(tmpnr); tmpnr = NULL;
    390                                                 treffer = 1;
    391                                                 break;
    392                                         }
    393287                                        free(tmpnr); tmpnr = NULL;
     288                                        cadescnode = cadescnode->next;
     289                                        continue;
    394290                                }
    395                                 dvbnode = dvbnode->next;
    396                         }
    397 
    398                         if(treffer == 0)
    399                         {
    400                                 cadescnode = cadescnode->next;
    401                                 continue;
     291                                free(tmpnr); tmpnr = NULL;
    402292                        }
    403293                }
     
    408298
    409299                        buf[pos++] = 0x09; //ca desc tag
    410                         if(round == 0 && status.caskipprivat == 1) //workaround for to long capmt
     300                        if(flag == 0 && status.caskipprivat == 1) //workaround for to long capmt
    411301                        {
    412302                                buf[pos++] = 4;
     
    445335
    446336                cadescnode = node->channel->cadesc;
    447                 while(cadescnode != NULL && clear == 0)
     337                while(cadescnode != NULL && flag < 2)
    448338                {
    449339                        if(cadescnode->len > 0 && cadescnode->pid == esinfonode->pid)
    450340                        {
     341                                //remove caids, cam can't
     342                                if(flag == 0 && status.casendallcaids == 0)
     343                                {
     344                                        char* tmpnr = NULL;
     345
     346                                        if(dvbnode != NULL)
     347                                        {
     348                                                tmpnr = oitoa(cadescnode->systemid);
     349                                                if(ostrstr(dvbnode->caslot->caids, tmpnr) == NULL)
     350                                                {
     351                                                        free(tmpnr); tmpnr = NULL;
     352                                                        cadescnode = cadescnode->next;
     353                                                        continue;
     354                                                }
     355                                                free(tmpnr); tmpnr = NULL;
     356                                        }
     357                                }
     358
    451359                                if(eslen == 0)
    452360                                {
     
    476384        }
    477385
    478         lenbytes = writelengthfield(&buf[3], pos - 10);
     386        *lenbytes = writelengthfield(&buf[3], pos - 10);
    479387        for(i = 0; i < pos + 10; i++)
    480388        {
    481                 buf[lenbytes + 3 + i] = buf[10 + i];
    482         }
    483         pos = pos - 10 + lenbytes + 3;
    484         tmppos = tmppos - 10 + lenbytes + 3;
     389                buf[(*lenbytes) + 3 + i] = buf[10 + i];
     390        }
     391        pos = pos - 10 + (*lenbytes) + 3;
     392        tmppos = tmppos - 10 + (*lenbytes) + 3;
    485393
    486394        //programinfo len
    487         buf[8 + lenbytes] = (tmppos - 9 - lenbytes) & 0xff;
    488         buf[7 + lenbytes] = ((tmppos - 9 - lenbytes) >> 8) & 0x0f;
    489 
    490         if(round == 0)
    491         {
    492 #ifdef CAMSUPP
    493                 if(caservice[caservicenr].caslot == NULL || clear > 0)
    494                         sendcapmttocam(node, buf, pos, caservicenr, lenbytes + 9, clear);
    495 #endif
    496                 if(clear == 0)
    497                 {
    498                         round = 1;
    499                         goto start;
    500                 }
    501         }
    502         else
    503         {
     395        buf[8 + (*lenbytes)] = (tmppos - 9 - (*lenbytes)) & 0xff;
     396        buf[7 + (*lenbytes)] = ((tmppos - 9 - (*lenbytes)) >> 8) & 0x0f;
     397
     398        return pos;
     399}
     400
     401//flag 0 = from zap
     402//flag 1 = from watchthread
     403//flag 2 = from cathread / caservicedel
     404//flag 3 = from recordthread
     405void sendcapmt(struct service* node, int clear, int flag)
     406{
     407        int len = 0, i = 0, caservicenr = 0, lenbytes = 0;
     408        unsigned char* buf = NULL;
     409        struct dvbdev* dvbnode = dvbdev;
     410
     411        //check if service should decrypt
     412        if(node == NULL)
     413        {
     414                debug(620, "service empty");
     415                return;
     416        }
     417        if(node->channel == NULL)
     418        {
     419                debug(620, "channel empty");
     420                return;
     421        }
     422        if(node->fedev == NULL)
     423        {
     424                debug(620, "no frontend");
     425                return;
     426        }
     427       
     428        if(node->channel->crypt == 0)
     429        {
     430                debug(620, "channel not crypt");
     431
     432                //check if we can change input sources
     433                int doswitch = 1;
     434                for(i = 0; i < MAXCASERVICE; i++)
     435                {
     436                        if(caservice[i].caslot != NULL && caservice[i].service != NULL && caservice[i].service->fedev != NULL)
     437                        {
     438                                if(caservice[i].service->fedev->devnr == node->fedev->devnr && (caservice[i].service->type == RECORDDIRECT || caservice[i].service->type == RECORDTIMER))
     439                                {
     440                                        debug(620, "can't change input sources");
     441                                        doswitch = 0;
     442                                }
     443                        }
     444                }
     445
     446                if(doswitch == 1)
     447                {
     448                        debug(200, "reset routing tuner %d", node->fedev->devnr);
     449                        switch(node->fedev->devnr)
     450                        {
     451                                case 0: setcisource(node->fedev->devnr, "A"); break;
     452                                case 1: setcisource(node->fedev->devnr, "B"); break;
     453                                case 2: setcisource(node->fedev->devnr, "C"); break;
     454                                case 3: setcisource(node->fedev->devnr, "D"); break;
     455                        }
     456                }
     457               
     458                return;
     459        }
     460       
     461        if(node->channel->pmt == NULL)
     462        {
     463                debug(620, "pmt empty");
     464                return;
     465        }
     466        if(node->channel->cadesc == NULL)
     467        {
     468                debug(620, "cadesc empty");
     469                return;
     470        }
     471        if(node->channel->esinfo == NULL)
     472        {
     473                debug(620, "esinfo empty");
     474                return;
     475        }
     476        if(node->fedev->type == FRONTENDDEVDUMMY)
     477        {
     478                debug(620, "dummy frontend not crypt");
     479                return;
     480        }
     481        if(flag != 3 && node->type != CHANNEL && node->type != RECORDDIRECT && node->type != RECORDTIMER && node->type != RECORDTIMESHIFT && node->type != RECORDSTREAM)
     482        {
     483                debug(620, "service type should not decrypt");
     484                return;
     485        }
     486
     487        buf = malloc(MINMALLOC);
     488        if(buf == NULL)
     489        {
     490                err("no mem");
     491                return;
     492        }
     493
     494        if(clear == 0)
     495        {
     496                caservicenr = caserviceadd(node, flag);
     497                if(caservicenr < 0)
     498                {
     499                        debug(620, "service is decrypt");
     500                        free(buf);
     501                        return;
     502                }
     503
     504                while(dvbnode != NULL)
     505                {
     506                        if(dvbnode->type == CIDEV && dvbnode->fd > -1 && dvbnode->caslot != NULL && dvbnode->caslot->status == 2 && dvbnode->caslot->caids != NULL)
     507                        {
     508                                if(caservice[caservicenr].caslot == NULL)
     509                                {
     510                                        lenbytes = 0;
     511                                        len = createcapmt(dvbnode, node, buf, &lenbytes, 0);
     512                                        if(len > -1)
     513                                        {
     514                                                if(sendcapmttocam(dvbnode, node, buf, len, caservicenr, lenbytes + 9, clear) == 0) break;
     515                                        }
     516                                }
     517                        }
     518                        dvbnode = dvbnode->next;
     519                }
     520
    504521                if(caservice[caservicenr].camsockfd < 0)
    505                         sendcapmttosock(node, buf, pos, caservicenr);
     522                {
     523                        lenbytes = 0;
     524                        len = createcapmt(NULL, node, buf, &lenbytes, 1);
     525                        if(len > -1)
     526                                sendcapmttosock(node, buf, len, caservicenr);
     527                }
     528        }
     529
     530        if(clear > 0)
     531        {
     532                while(dvbnode != NULL)
     533                {
     534                        if(dvbnode->type == CIDEV && dvbnode->fd > -1 && dvbnode->caslot != NULL && dvbnode->caslot->status == 2 && dvbnode->caslot->caids != NULL)
     535                        {
     536                                if(caservice[clear - 1].caslot == dvbnode->caslot)
     537                                {
     538                                        lenbytes = 0;
     539                                        len = createcapmt(dvbnode, node, buf, &lenbytes, 2);
     540                                        if(len > -1)
     541                                                sendcapmttocam(dvbnode, node, buf, len, caservicenr, lenbytes + 9, clear);
     542                                        break;
     543                                }
     544                        }
     545                        dvbnode = dvbnode->next;
     546                }
    506547        }
    507548
Note: See TracChangeset for help on using the changeset viewer.