Changeset 1618


Ignore:
Timestamp:
02/19/10 17:51:22 (11 years ago)
Author:
_network
Message:

module-dvbapi
-fix memleak/improve theard handling (thx pacco_dt)
-process emm for inactive cards

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/module-dvbapi.c

    r1584 r1618  
    2323#include "globals.h"
    2424
    25 #define BUFSIZE 1024
     25#define BUFSIZE 512
    2626#define MAX_DEMUX 5
    2727#define MAX_CAID 50
     
    5757    unsigned char lastcw0[8];
    5858    unsigned char lastcw1[8];
     59    pthread_t descramble_thread;
     60    unsigned int thread_active;
    5961} DEMUXTYPE;
    6062#define DMX_FILTER_SIZE 16
     
    127129
    128130unsigned short global_caid_list[MAX_CAID];
    129 CAIDTAB prioritytab;
    130 unsigned short ignoretab[CS_MAXCAIDTAB];
     131CAIDTAB prioritytab,ignoretab;
    131132
    132133#define BOX_COUNT 2
     
    249250int dvbapi_read_device(int dmx_fd, unsigned char *buf, int length, int debug)
    250251{
    251     int len;
    252     len=read(dmx_fd, buf, length);
     252    int len, rc;
     253    struct pollfd pfd[1];
     254
     255    pfd[0].fd = dmx_fd;
     256    pfd[0].events = (POLLIN | POLLPRI);
     257
     258    rc = poll(pfd, 1, 5000);
     259    if (rc<1)
     260        return -1;
     261
     262    len = read(dmx_fd, buf, length);
    253263
    254264    if (len==-1)
     
    362372    int dmx_fd, len;
    363373
    364     dmx_fd=demux[demux_index].demux_ecm_fd;
     374    dmx_fd=demux[demux_index].demux_emm_fd;
    365375
    366376    dvbapi_set_filter(dmx_fd, selected_api, 0x0001, 0x01, 0xFF, 2000);
     
    387397    }
    388398
     399    dvbapi_stop_filter(demux_index, 1);
     400
    389401    return;
    390402}
     
    404416
    405417    if (demux[demux_id].demux_ecm_fd>0) {
    406         ioctl(demux[demux_id].demux_ecm_fd,DMX_STOP);
     418        dvbapi_stop_filter(demux_id, 0);
    407419        close(demux[demux_id].demux_ecm_fd);
    408420        demux[demux_id].demux_ecm_fd=0;
     
    410422
    411423    if (demux[demux_id].demux_emm_fd>0) {
    412         ioctl(demux[demux_id].demux_emm_fd,DMX_STOP);
     424        dvbapi_stop_filter(demux_id, 1);
    413425        close(demux[demux_id].demux_emm_fd);
    414426        demux[demux_id].demux_emm_fd=0;
     427    }
     428
     429    if (demux[demux_id].thread_active == 0) {
     430        pthread_cancel(demux[demux_id].descramble_thread);
     431        pthread_join(demux[demux_id].descramble_thread, NULL);
     432        demux[demux_id].thread_active = -1;
    415433    }
    416434
     
    464482    demux[demux_index].provider_id=provider_id;
    465483
    466 
    467484    int camfd=dvbapi_open_device(demux_index,1);
    468485    if (camfd<=0) {
     
    499516
    500517        dvbapi_stop_filter(demux_index,0);
    501         dvbapi_stop_filter(demux_index,1);
    502518
    503519        cs_debug("dvbapi: trying CA_System_ID: %04x CA_PID: %04x EEM_PID: %04x", demux[demux_index].ECMpids[n].CA_System_ID, demux[demux_index].ECMpids[n].CA_PID, demux[demux_index].ECMpids[n].EMM_PID);
     
    512528        }
    513529
    514         if (cfg->dvbapi_au==1)
    515         {
     530        if (cfg->dvbapi_au==1) {
     531            dvbapi_stop_filter(demux_index,1);
    516532            if (demux[demux_index].ECMpids[n].EMM_PID>0)
    517533                provid=dvbapi_get_provid(demux_index, demux[demux_index].ECMpids[n].EMM_PID);
    518534        }
    519535
    520         //cs_log("Provider ID: %04x", provid);
    521 
    522536        //grep ecm
    523537        dvbapi_get_single_ecm(demux_index, demux[demux_index].ECMpids[n].CA_System_ID, demux[demux_index].ECMpids[n].CA_PID, provid);
     
    530544{
    531545    int demux_index=(int)di;
    532     int dmx1_fd,dmx2_fd,n=30,k=0;
     546    int dmx1_fd,dmx2_fd=0,n=30,k=0;
    533547    unsigned int program_number;
    534548
     549    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
     550    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
     551
    535552    cs_debug("dvbapi: Start descrambling Thread %d", demux_index);
    536553
    537     dmx1_fd = dvbapi_open_device(demux_index,0); //ECM,CAT
    538     dmx2_fd = dvbapi_open_device(demux_index,0); //EMM
    539 
     554    dmx1_fd = dvbapi_open_device(demux_index,0); //ECM
    540555    demux[demux_index].demux_ecm_fd=dmx1_fd;
    541     demux[demux_index].demux_emm_fd=dmx2_fd;
    542 
    543     dvbapi_parse_cat(demux_index);
     556   
     557    if (cfg->dvbapi_au==1) {
     558        dmx2_fd = dvbapi_open_device(demux_index,0); //EMM,CAT
     559        demux[demux_index].demux_emm_fd=dmx2_fd;
     560        dvbapi_parse_cat(demux_index);
     561    }
    544562
    545563    program_number=demux[demux_index].program_number;
     
    569587    }
    570588
    571 
    572     struct pollfd pfd2[MAX_DEMUX*2];
     589    struct pollfd pfd2[2];
    573590    int rc,len,i,pfdcount;
    574591    unsigned char buffer[BUFSIZE];
     
    576593    while(1)
    577594    {
    578 
    579595        pfdcount=0;
    580596
     
    587603            pfdcount++;
    588604        } else break;
    589         if (demux[demux_index].demux_emm_fd>0) {
    590             pfd2[pfdcount].fd = demux[demux_index].demux_emm_fd;
    591             pfd2[pfdcount].events = (POLLIN | POLLPRI);
    592             pfdcount++;
    593         } else break;
    594 
    595 
    596         rc=poll(pfd2, pfdcount, 1000);
     605        if (cfg->dvbapi_au==1) {
     606            if (demux[demux_index].demux_emm_fd>0) {
     607                pfd2[pfdcount].fd = demux[demux_index].demux_emm_fd;
     608                pfd2[pfdcount].events = (POLLIN | POLLPRI);
     609                pfdcount++;
     610            } else break;
     611        }
     612
     613        rc=poll(pfd2, pfdcount, 3000);
     614
     615        if (rc<0)
     616            break;
    597617
    598618        for (i = 0; i < pfdcount; i++) {
     
    614634                            cs_debug("Read %d bytes\tTable-id: %02x\tCA section length: %d", len, buffer[0], len);
    615635
    616                             if (len>0) {
    617                                 ECM_REQUEST *er;
    618 
    619                                 if (!(er=get_ecmtask()))
    620                                     continue;
    621 
    622                                 er->srvid = demux[demux_index].program_number;
    623                                 er->caid  = demux[demux_index].ca_system_id;
    624                                 er->prid  = demux[demux_index].provider_id;
    625 
    626                                 er->l=len;
    627                                 memcpy(er->ecm, buffer, er->l);
    628 
    629                                 get_cw(er);
    630                             }
     636                            ECM_REQUEST *er;
     637
     638                            if (!(er=get_ecmtask()))
     639                                continue;
     640
     641                            er->srvid = demux[demux_index].program_number;
     642                            er->caid  = demux[demux_index].ca_system_id;
     643                            er->prid  = demux[demux_index].provider_id;
     644
     645                            er->l=len;
     646                            memcpy(er->ecm, buffer, er->l);
     647
     648                            get_cw(er);
    631649                        }
    632650                    }
     
    635653                    //EMM
    636654
    637                     if (cfg->dvbapi_au!=1)
    638                         continue;
    639 
    640655                    cs_debug("EMM Type: 0x%02x", buffer[0]);
    641 
    642656                    cs_ddump(buffer, len, "emm:");
    643657
     
    665679    cs_debug("dvbapi: Stop descrambling Thread %d", demux_index);
    666680
    667     return 0;
     681    pthread_detach(pthread_self());
     682    pthread_exit(0);
    668683}
    669684
     
    688703                if (k+1>=MAX_CAID) break;
    689704                global_caid_list[k]=reader[i].caid[j];
    690                 k++;
    691                
     705                k++;               
    692706            }
    693707        }
    694708    }
    695709    for (n=0; n<demux[demux_index].ECMpidcount; n++) {
    696         if (dvbapi_check_array(ignoretab, CS_MAXCAIDTAB, demux[demux_index].ECMpids[n].CA_System_ID)>=0) {
     710        if (dvbapi_check_array(ignoretab.caid, CS_MAXCAIDTAB, demux[demux_index].ECMpids[n].CA_System_ID)>=0) {
    697711            cs_debug("-> ignore %04x", demux[demux_index].ECMpids[n].CA_System_ID);
    698712        } else if (dvbapi_check_array(global_caid_list, MAX_CAID, demux[demux_index].ECMpids[n].CA_System_ID)>=0) {
     
    725739}
    726740
     741void dvbapi_parse_descriptor(int demux_id, int i, unsigned int info_length, unsigned char *buffer) {
     742    //int ca_pmt_cmd_id = buffer[i + 5];
     743    unsigned int descriptor_length=0;
     744    ushort added,j,n;
     745
     746    for (j = 0; j < info_length - 1; j += descriptor_length + 2) {
     747        descriptor_length = buffer[i + j + 7];
     748        int descriptor_ca_system_id = (buffer[i + j + 8] << 8) | buffer[i + j + 9];
     749        int descriptor_ca_pid = ((buffer[i + j + 10] & 0x1F) << 8) | buffer[i + j + 11];
     750
     751        cs_debug("typ: %02x\tca_system_id: %04x\t ca_pid: %04x", buffer[i + j + 6], descriptor_ca_system_id, descriptor_ca_pid);
     752
     753        if (buffer[i + j + 6] == 0x09) {
     754            added=0;
     755            for (n=0;n<demux[demux_id].ECMpidcount;n++) {
     756                if (demux[demux_id].ECMpids[n].CA_System_ID==descriptor_ca_system_id)
     757                    added=1;
     758            }
     759            if (added==0) {
     760                demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CA_PID=descriptor_ca_pid;
     761                demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CA_System_ID=descriptor_ca_system_id;
     762                demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].EMM_PID=0;
     763                demux[demux_id].ECMpidcount++;
     764            }
     765        }
     766    }
     767}
     768
    727769// from tuxbox camd
    728770int dvbapi_parse_capmt(unsigned char *buffer, unsigned int length)
    729771{
    730     unsigned short i, j, u, n, added;
     772    unsigned short i, u;
    731773    unsigned short ca_mask=0x01, demux_index2=0x00;
    732774
     
    761803
    762804    for (i=0;i<MAX_DEMUX;i++) {
    763         if (demux[i].demux_index==demux_index2) {
    764             if (demux[i].program_number==((buffer[1] << 8) | buffer[2])) { // already descrambling prog on this device
    765                 if (demux[i].active==1) {
    766                     //remove any inactive program
    767                     for (u=0;u<MAX_DEMUX;u++) {
    768                         if (demux[u].demux_index==demux_index2 && demux[u].active==0)
    769                             dvbapi_stop_descrambling(u);
    770                         demux[u].active=0;
    771                     }
    772 
    773                 } else
    774                     demux[i].active=1;
    775                 return 0;
    776             }
     805        if (demux[i].demux_index==demux_index2 && demux[i].program_number==((buffer[1] << 8) | buffer[2])) { // already descrambling prog on this device
     806            if (demux[i].active==1) {
     807                //remove any inactive program
     808                for (u=0;u<MAX_DEMUX;u++) {
     809                    if (demux[u].demux_index==demux_index2 && demux[u].active==0)
     810                        dvbapi_stop_descrambling(u);
     811                    demux[u].active=0;
     812                }
     813            } else
     814                demux[i].active=1;
     815            return 0;
    777816        }
    778817    }
     
    814853
    815854    //CA_PIDS for all streams
    816     if (program_info_length != 0)
    817     {
    818         int ca_pmt_cmd_id = buffer[6];
    819         cs_debug("ca_pmt_id: %02x", ca_pmt_cmd_id);
    820         int descriptor_length=0;
    821         for (i = 0; i < program_info_length - 1; i += descriptor_length + 2)
    822         {
    823             descriptor_length = buffer[i + 8];
    824             int ca_system_id = (buffer[i + 9] << 8) | buffer[i + 10];
    825             int ca_pid = ((buffer[i + 11] & 0x1F) << 8)| buffer[i + 12];
    826 
    827             cs_debug("typ: %02x ca_system_id: %04x\t ca_pid: %04x\tca_descriptor_length %d", buffer[i + 7], ca_system_id, ca_pid, descriptor_length);
    828 
    829             if (buffer[i + 7] == 0x09) {
    830                 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CA_PID=ca_pid;
    831                 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CA_System_ID=ca_system_id;
    832                 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].EMM_PID=0;
    833                 demux[demux_id].ECMpidcount++;
    834             }
    835         }
     855    if (program_info_length != 0) {
     856        dvbapi_parse_descriptor(demux_id, 1, program_info_length, buffer);
    836857    }
    837858
     
    849870        demux[demux_id].STREAMpidcount++;
    850871
    851         if (es_info_length != 0)
    852         {
    853             int ca_pmt_cmd_id = buffer[i + 5];
    854             cs_debug("dvbapi: ca_pmt_cmd_id 0x%02x", ca_pmt_cmd_id);
    855             unsigned int descriptor_length=0;
    856             for (j = 0; j < es_info_length - 1; j += descriptor_length + 2)
    857             {
    858                 descriptor_length = buffer[i + j + 7];
    859                 int descriptor_ca_system_id = (buffer[i + j + 8] << 8) | buffer[i + j + 9];
    860                 int descriptor_ca_pid = ((buffer[i + j + 10] & 0x1F) << 8) | buffer[i + j + 11];
    861 
    862                 cs_debug("typ: %02x\tca_system_id: %04x\t ca_pid: %04x", buffer[i + j + 6], descriptor_ca_system_id, descriptor_ca_pid);
    863 
    864                 if (buffer[i + j + 6] == 0x09) {
    865                     added=0;
    866                     for (n=0;n<demux[demux_id].ECMpidcount;n++) {
    867                         if (demux[demux_id].ECMpids[n].CA_System_ID==descriptor_ca_system_id)
    868                             added=1;
    869                     }
    870                     if (added==0) {
    871                         demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CA_PID=descriptor_ca_pid;
    872                         demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CA_System_ID=descriptor_ca_system_id;
    873                         demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].EMM_PID=0;
    874                         demux[demux_id].ECMpidcount++;
    875                     }
    876                 }
    877             }
    878         }
    879     }
    880 
    881     pthread_t p3;
    882 
    883     cs_log("dvbapi: Found %d ECMpids in PMT", demux[demux_id].ECMpidcount);
    884     cs_debug("dvbapi: Found %d STREAMpids in PMT", demux[demux_id].STREAMpidcount);
     872        if (es_info_length != 0) {
     873            dvbapi_parse_descriptor(demux_id, i, es_info_length, buffer);
     874        }
     875    }
     876
     877    cs_debug("dvbapi: Found %d ECMpids and %d STREAMpids in PMT", demux[demux_id].ECMpidcount);
    885878
    886879    if (demux[demux_id].ECMpidcount>0) {
    887880        dvbapi_resort_ecmpids(demux_id);
    888         if (demux[demux_id].ECMpidcount>0)
    889             pthread_create (&p3, NULL, thread_descrambling, (void*)demux_id);
    890     }
    891 
     881        if (demux[demux_id].ECMpidcount>0) {}
     882            demux[demux_id].thread_active=pthread_create(&demux[demux_id].descramble_thread, NULL, thread_descrambling, (void*)demux_id);
     883    }
    892884
    893885    return 0;
     
    974966    while(1)
    975967    {
    976         cs_sleepms(1000); // check every second
     968        cs_sleepms(500);
    977969        //cs_debug("dvbapi: check zap");
    978970
     
    992984
    993985        // if message begins with an apdu_tag and is longer than three bytes
    994 
    995986        if ((buffer[0] == 0x9F) && ((buffer[1] >> 7) == 0x01) && ((buffer[2] >> 7) == 0x00)) {
    996987            dvbapi_handlesockmsg(buffer, len);
     
    1007998}
    1008999
    1009 
     1000void dvbapi_chk_caidtab(char *caidasc, CAIDTAB *ctab) {
     1001
     1002    char *ptr1, *ptr3;
     1003    int i;
     1004
     1005    for (i=0, ptr1=strtok(caidasc, ","); (i<CS_MAXCAIDTAB) && (ptr1); ptr1=strtok(NULL, ","))
     1006    {
     1007        unsigned long caid, prov;
     1008        if( (ptr3=strchr(trim(ptr1), ':')) )
     1009            *ptr3++='\0';
     1010        else
     1011            ptr3="";
     1012
     1013        if (((caid=a2i(ptr1, 2))|(prov=a2i(ptr3, 3))) < 0x10000)
     1014        {
     1015            ctab->caid[i]=caid;
     1016            ctab->mask[i]=prov;
     1017            i++;
     1018        }
     1019    }
     1020}
    10101021
    10111022int dvbapi_main_local()
     
    10201031
    10211032    if (cfg->dvbapi_boxtype[0]==0) {
    1022         strncpy(cfg->dvbapi_boxtype, "dreambox", sizeof(cfg->dvbapi_boxtype)-1);
     1033        cs_strncpy(cfg->dvbapi_boxtype, "dreambox", sizeof(cfg->dvbapi_boxtype));
    10231034        cs_log("dvbapi: boxtype not set. Assume boxtype=%s.", cfg->dvbapi_boxtype);
    10241035    } else
     
    10361047        demux[i].ca_fd=0;
    10371048        demux[i].demux_index=-1;
    1038 
     1049        demux[i].thread_active = -1;
    10391050        memset(demux[i].buffer_cache_dmx,0 ,12);
    10401051    }
     
    10531064    }
    10541065
    1055     char *ptr1, *ptr3;
    1056     //priority
    1057     for (i=0, ptr1=strtok(cfg->dvbapi_priority, ","); (i<CS_MAXCAIDTAB) && (ptr1); ptr1=strtok(NULL, ","))
    1058     {
    1059         unsigned long caid, prov;
    1060         if( (ptr3=strchr(trim(ptr1), ':')) )
    1061             *ptr3++='\0';
    1062         else
    1063             ptr3="";
    1064 
    1065         if (((caid=a2i(ptr1, 2))|(prov=a2i(ptr3, 3))) < 0x10000)
    1066         {
    1067             prioritytab.caid[i]=caid;
    1068             prioritytab.mask[i]=prov;
    1069             i++;
    1070         }
    1071     }
    1072     //ignore
    1073     for (i=0, ptr1=strtok(cfg->dvbapi_ignore, ","); (i<CS_MAXCAIDTAB) && (ptr1); ptr1=strtok(NULL, ","))
    1074     {
    1075         unsigned long caid, prov;
    1076         if( (ptr3=strchr(trim(ptr1), ':')) )
    1077             *ptr3++='\0';
    1078         else
    1079             ptr3="";
    1080 
    1081         if (((caid=a2i(ptr1, 2))|(prov=a2i(ptr3, 3))) < 0x10000)
    1082         {
    1083             ignoretab[i]=caid;
    1084             i++;
    1085         }
    1086     }
     1066    dvbapi_chk_caidtab(cfg->dvbapi_priority, &prioritytab);
     1067    dvbapi_chk_caidtab(cfg->dvbapi_ignore, &ignoretab);
    10871068
    10881069    pfd2[0].fd = fd_m2c;
     
    10991080            cs_exit(0);
    11001081
    1101 
    11021082        chk_pending(tp);
    11031083
     
    11281108    memcpy(cw_1, er->cw+8, 8);
    11291109
    1130     for (i=0;i<MAX_DEMUX;i++)
    1131     {
    1132         if (demux[i].program_number==er->srvid)
    1133         {
    1134 
     1110    for (i=0;i<MAX_DEMUX;i++) {
     1111        if (demux[i].program_number==er->srvid) {
    11351112            if (er->rc<=2 && demux[i].ca_system_id==0 && er->caid!=0) {
     1113                dvbapi_start_descrambling(i, er->caid, er->pid, er->prid);
     1114            }
     1115
     1116            if (er->rc==4 && cfg->dvbapi_au==1 && dvbapi_check_array(global_caid_list, MAX_CAID, er->caid)>=0) {
     1117                //local card and not found -> maybe card need emm
    11361118                dvbapi_start_descrambling(i, er->caid, er->pid, er->prid);
    11371119            }
     
    11451127            memset(&ca_descr,0,sizeof(ca_descr));
    11461128
    1147             if (demux[i].ca_fd<=0)
    1148             {
     1129            if (demux[i].ca_fd<=0) {
    11491130                cs_log("dvbapi: could not write cw.");
    11501131                return;
    11511132            }
    11521133
    1153             if (memcmp(cw_0,demux[i].lastcw0,8)!=0 && memcmp(cw_0,nullcw,8)!=0)
    1154             {
     1134            if (memcmp(cw_0,demux[i].lastcw0,8)!=0 && memcmp(cw_0,nullcw,8)!=0) {
    11551135                ca_descr.index = i;
    11561136                ca_descr.parity = 0;
     
    11621142            }
    11631143
    1164             if (memcmp(cw_1,demux[i].lastcw1,8)!=0 && memcmp(cw_1,nullcw,8)!=0)
    1165             {
     1144            if (memcmp(cw_1,demux[i].lastcw1,8)!=0 && memcmp(cw_1,nullcw,8)!=0) {
    11661145                ca_descr.index = i;
    11671146                ca_descr.parity = 1;
     
    11971176
    11981177    int ok=0;
    1199 
    12001178    if( !account )
    12011179    {
Note: See TracChangeset for help on using the changeset viewer.