diff -Nru oscam-1.20-10210~r9982/csctapi/ifd_sci.c oscam-1.20-10217~r9989/csctapi/ifd_sci.c --- oscam-1.20-10210~r9982/csctapi/ifd_sci.c 2014-11-05 22:24:19.000000000 +0000 +++ oscam-1.20-10217~r9989/csctapi/ifd_sci.c 2014-11-08 16:02:27.000000000 +0000 @@ -23,6 +23,7 @@ struct sr_data { + uint8_t old_reset; unsigned char T; uint32_t fs; uint32_t ETU; @@ -34,6 +35,9 @@ unsigned char I; }; +static int32_t init_count; +static int32_t current_count; + static int32_t Sci_GetStatus(struct s_reader *reader, int32_t *status) { ioctl(reader->handle, IOCTL_GET_IS_CARD_PRESENT, status); @@ -215,6 +219,7 @@ static int32_t Sci_Reset(struct s_reader *reader, ATR *atr) { int32_t ret = ERROR; + struct sr_data *crdr_data = reader->crdr_data; rdr_debug_mask(reader, D_IFD, "Reset internal cardreader!"); SCI_PARAMETERS params; @@ -257,13 +262,44 @@ cs_sleepms(150); ioctl(reader->handle, IOCTL_SET_PARAMETERS, ¶ms); cs_sleepms(150); // give the reader some time to process the params - ioctl(reader->handle, IOCTL_SET_RESET, 1); - ret = Sci_Read_ATR(reader, atr); - params.fs = 0; // fs 0 heals unresponsive readers due to incorrect previous parameters before box needed powercycle (tested working on XP1000 box) - tries++; // increase fs - if(ret == ERROR) { rdr_debug_mask(reader, D_IFD, "Read ATR fail, attempt %d/5 now trying fs = %d to recover", tries, params.fs); } + if(reader->sh4_stb || crdr_data->old_reset) + { + rdr_log(reader," using sh4 or old reset"); + ioctl(reader->handle, IOCTL_SET_RESET, 1); + ret = Sci_Read_ATR(reader, atr); + params.fs = 0; // fs 0 heals unresponsive readers due to incorrect previous parameters before box needed powercycle (tested working on XP1000 box) + tries++; // increase fs + if(ret == ERROR) { rdr_debug_mask(reader, D_IFD, "Read ATR fail, attempt %d/5 now trying fs = %d to recover", tries, params.fs); } + } + else + { + if(ioctl(reader->handle, IOCTL_SET_ATR_READY, NULL) < 0) + { + ret = ERROR; + rdr_log(reader, "Error:%s ioctl(IOCTL_SET_ATR_READY) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) ); + } + else + { + if(ioctl(reader->handle, IOCTL_SET_RESET, NULL) < 0) + { + ret = ERROR; + rdr_log(reader, "Error:%s ioctl(IOCTL_SET_ATR_READY) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) ); + } + else + { + ret = Sci_Read_ATR(reader, atr); + } + + if(ret == ERROR) + { + params.fs = 0; // fs 0 heals unresponsive readers due to incorrect previous parameters before box needed powercycle (tested working on XP1000 box) + tries++; // increase fs + rdr_log(reader, "Read ATR fail, attempt %d/5 now trying fs = %d to recover", tries, params.fs); + } + } + } } - ioctl(reader->handle, IOCTL_SET_ATR_READY, 1); + if(reader->sh4_stb || crdr_data->old_reset){ioctl(reader->handle, IOCTL_SET_ATR_READY, 1);} return ret; } @@ -271,15 +307,6 @@ { cs_sleepms(150); struct sr_data *crdr_data = reader->crdr_data; - crdr_data->T = T; - crdr_data->fs = fs; - crdr_data->ETU = ETU; - crdr_data->WWT = WWT; - crdr_data->CWT = CWT; - crdr_data->BWT = BWT; - crdr_data->EGT = EGT; - crdr_data->P = P; - crdr_data->I = I; //int32_t n; SCI_PARAMETERS params; //memset(¶ms,0,sizeof(SCI_PARAMETERS)); @@ -299,7 +326,17 @@ if(I) { params.I = I; } - rdr_debug_mask(reader, D_IFD, "Setting reader T=%d fs=%d ETU=%d WWT=%d CWT=%d BWT=%d EGT=%d clock=%d check=%d P=%d I=%d U=%d", + crdr_data->T = params.T; + crdr_data->fs = params.fs; + crdr_data->ETU = params.ETU; + crdr_data->WWT = params.WWT; + crdr_data->CWT = params.CWT; + crdr_data->BWT = params.BWT; + crdr_data->EGT = params.EGT; + crdr_data->P = params.P; + crdr_data->I = params.I; + + rdr_log(reader, "Sended reader settings T=%d fs=%d ETU=%d WWT=%d CWT=%d BWT=%d EGT=%d clock=%d check=%d P=%d I=%d U=%d", (int)params.T, params.fs, (int)params.ETU, (int)params.WWT, (int)params.CWT, (int)params.BWT, (int)params.EGT, (int)params.clock_stop_polarity, (int)params.check, @@ -329,7 +366,12 @@ static int32_t Sci_Deactivate(struct s_reader *reader) { rdr_debug_mask(reader, D_IFD, "Deactivating card"); + struct sr_data *crdr_data = reader->crdr_data; + if(reader->sh4_stb || crdr_data->old_reset){ ioctl(reader->handle, IOCTL_SET_DEACTIVATE); + } else { + ioctl(reader->handle, IOCTL_SET_DEACTIVATE, NULL); + } return OK; } @@ -337,10 +379,33 @@ { struct sr_data *crdr_data = reader->crdr_data; int32_t ret; - ioctl(reader->handle, IOCTL_SET_RESET, 1); - ret = Sci_Read_ATR(reader, atr); - ioctl(reader->handle, IOCTL_SET_ATR_READY, 1); - + if(reader->sh4_stb || crdr_data->old_reset) + { + ioctl(reader->handle, IOCTL_SET_RESET, 1); + ret = Sci_Read_ATR(reader, atr); + ioctl(reader->handle, IOCTL_SET_ATR_READY, 1); + } + else + { + if(ioctl(reader->handle, IOCTL_SET_ATR_READY, NULL) < 0) + { + ret = ERROR; + rdr_log(reader, "Error:%s ioctl(IOCTL_SET_ATR_READY) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) ); + } + else + { + if(ioctl(reader->handle, IOCTL_SET_RESET, NULL) < 0) + { + ret = ERROR; + rdr_log(reader, "Error:%s ioctl(IOCTL_SET_ATR_READY) failed.(%d:%s)", __FUNCTION__, errno, strerror(errno) ); + } + else + { + ret = Sci_Read_ATR(reader, atr); + } + } + } + cs_sleepms(150); Sci_WriteSettings(reader, crdr_data->T,crdr_data->fs,crdr_data->ETU, crdr_data->WWT,crdr_data->CWT,crdr_data->BWT,crdr_data->EGT,crdr_data->P,crdr_data->I); cs_sleepms(150); return ret; @@ -348,6 +413,12 @@ static int32_t Sci_Init(struct s_reader *reader) { + if(!init_count) {init_count = 0;} + if(init_count < current_count) {rdr_log(reader,"Waiting on reader_closed before restarting");} + while (init_count < current_count) // Restarting the reader while it was not closed does cause segfault. + { + cs_sleepms(1000); + } int flags = O_RDWR | O_NOCTTY; #if defined(__SH4__) || defined(STB04SCI) flags |= O_NONBLOCK; @@ -362,6 +433,10 @@ if(!reader->crdr_data && !cs_malloc(&reader->crdr_data, sizeof(struct sr_data))) { return ERROR; } + struct sr_data *crdr_data = reader->crdr_data; + crdr_data->old_reset = 1; + init_count++; + current_count++; return OK; } @@ -383,8 +458,11 @@ static int32_t Sci_Close(struct s_reader *reader) { + --init_count; Sci_Deactivate(reader); IO_Serial_Close(reader); + cs_sleepms(300); // some stb's needs small extra time even after close procedure seems to be ok. + --current_count; return OK; } @@ -395,11 +473,13 @@ // P fixed at 5V since this is default class A card, and TB is deprecated if(reader->protocol_type != ATR_PROTOCOL_TYPE_T14) // fix VU+ internal reader slow responses on T0/T1 { + cs_sleepms(150); call(Sci_WriteSettings(reader, 0, reader->divider, ETU, WWT, CWT, BWT, EGT, 5, (unsigned char)I)); cs_sleepms(150); } else // no fixup for T14 protocol otherwise error { + cs_sleepms(150); call(Sci_WriteSettings(reader, reader->protocol_type, reader->divider, ETU, WWT, CWT, BWT, EGT, 5, (unsigned char)I)); cs_sleepms(150); } @@ -407,6 +487,7 @@ else // all other brand boxes than dreamboxes or VU+! { // P fixed at 5V since this is default class A card, and TB is deprecated + cs_sleepms(150); call(Sci_WriteSettings(reader, reader->protocol_type, F, ETU, WWT, CWT, BWT, EGT, 5, (unsigned char)I)); cs_sleepms(150); } diff -Nru oscam-1.20-10210~r9982/debian/changelog oscam-1.20-10217~r9989/debian/changelog --- oscam-1.20-10210~r9982/debian/changelog 2014-11-05 22:24:31.000000000 +0000 +++ oscam-1.20-10217~r9989/debian/changelog 2014-11-08 16:02:40.000000000 +0000 @@ -1,97 +1,59 @@ -oscam (1.20-10210~r9982-utopic) utopic; urgency=medium +oscam (1.20-10217~r9989-utopic) utopic; urgency=medium - * [r9982] - - Fix compilation with disabled WebIf. - - Commit r9981 intrduced a bug that prevented oscam from building when - the webif was disabled. This commit fixes the build and ticket #3979. - - - * [r9981] - - add WebifPort: to oscam.version - now its possible to read out for activity link in openwebif and link them to the main menu - - - - - * [r9980] - - -refresh fix - please delete browser cache !!! + * [r9989] + - DVBAPI: Some rework on emm filtering - * [r9979] - - removed unexpected ecm response spam on unhandled (could be timeout!) - - added workaround for bad peers ecm responses if only last controlword crc is invalid (cw is actually working if we fix the last cw crc!) + * [r9988] + - Fixed returncode in case of failure camd35 emmsend - * [r9978] - fix httprefresh + * [r9987] - * [r9977] + - Cleanout notfound cache responses too so they can be asked again - Fix r9925 in case when doing api call - Thx to 3PO + * [r9986] + sci_reader - * [r9976] + small typo in protection against restarting whitout having the reader closed. 3000 to 300 ms - fix jumpy pages - thnx to Hook + * [r9985] - * [r9975] + reader_sci - fix sorting + init procedure off before used since with sci9983 and 9984 there was an error with two cards. - * [r9974] + * [r9984] - -change Graph page - -change position of ECM Unique - -change show raw names in cccam entitlements + sci_reader + sh4 stb did not worked with svn9833 added exception for sh4 to card init and card reset - * [r9973] - sci reader + * [r9983] - some fixes and extra delay after writing settings. + - Some recode and errorlog for internal readers - * [r9972] - fix small typo on cccam share - - - * [r9971] - - fix temporary block for cccam proto - - - * [r9970] - - sci reader - - General small timeout aplied for al readers after card reset init and settings write. - - - * [r9969] + * [r9982] - sci reader + Fix compilation with disabled WebIf. - sh4 needs some time after changing settings. Now it clocks ok + Commit r9981 intrduced a bug that prevented oscam from building when + the webif was disabled. This commit fixes the build and ticket #3979. - -- Andrey Pavlenko Thu, 06 Nov 2014 01:24:30 +0300 + -- Andrey Pavlenko Sat, 08 Nov 2014 19:02:38 +0300 diff -Nru oscam-1.20-10210~r9982/module-camd35.c oscam-1.20-10217~r9989/module-camd35.c --- oscam-1.20-10210~r9982/module-camd35.c 2014-11-05 22:24:19.000000000 +0000 +++ oscam-1.20-10217~r9989/module-camd35.c 2014-11-08 16:02:27.000000000 +0000 @@ -1303,8 +1303,9 @@ struct s_client *cl = cur_client(); - if(!tcp_connect(cl)) { return -1; } - + if(!tcp_connect(cl)) { return 0; } + cl->reader->card_status = CARD_INSERTED; //for udp + memset(buf, 0, 20); memset(buf + 20, 0xff, ep->emmlen + 15); diff -Nru oscam-1.20-10210~r9982/module-dvbapi.c oscam-1.20-10217~r9989/module-dvbapi.c --- oscam-1.20-10210~r9982/module-dvbapi.c 2014-11-05 22:24:19.000000000 +0000 +++ oscam-1.20-10217~r9989/module-dvbapi.c 2014-11-08 16:02:27.000000000 +0000 @@ -118,7 +118,6 @@ uint16_t caid; uint32_t provid; uint16_t pid; - int32_t count; uint32_t num; struct timeb time_started; }; @@ -221,7 +220,7 @@ return count; } -int32_t add_emmfilter_to_list(int32_t demux_id, uchar *filter, uint16_t caid, uint32_t provid, uint16_t emmpid, int32_t count, int32_t num, bool enable) +int32_t add_emmfilter_to_list(int32_t demux_id, uchar *filter, uint16_t caid, uint32_t provid, uint16_t emmpid, int32_t num, bool enable) { if(!ll_emm_active_filter) { ll_emm_active_filter = ll_create("ll_emm_active_filter"); } @@ -241,7 +240,6 @@ filter_item->caid = caid; filter_item->provid = provid; filter_item->pid = emmpid; - filter_item->count = count; filter_item->num = num; if (enable){ cs_ftime(&filter_item->time_started); @@ -522,7 +520,8 @@ return 0; } -int32_t dvbapi_set_filter(int32_t demux_id, int32_t api, uint16_t pid, uint16_t caid, uint32_t provid, uchar *filt, uchar *mask, int32_t timeout, int32_t pidindex, int32_t count, int32_t type, int8_t add_to_emm_list) +int32_t dvbapi_set_filter(int32_t demux_id, int32_t api, uint16_t pid, uint16_t caid, uint32_t provid, uchar *filt, uchar *mask, int32_t timeout, int32_t pidindex, int32_t type, + int8_t add_to_emm_list) { #if defined WITH_AZBOX || defined WITH_MCA openxcas_caid = demux[demux_id].ECMpids[pidindex].CAID; @@ -547,7 +546,6 @@ demux[demux_id].demux_fd[n].caid = caid; demux[demux_id].demux_fd[n].provid = provid; demux[demux_id].demux_fd[n].type = type; - demux[demux_id].demux_fd[n].count = count; switch(api) { @@ -635,7 +633,7 @@ { cs_debug_mask(D_DVBAPI, "[DVBAPI] Demuxer #%d Filter #%d started successfully (caid %04X provid %06X pid %04X)", demux_id, n + 1, caid, provid, pid); if(type == TYPE_EMM && add_to_emm_list){ - add_emmfilter_to_list(demux_id, filt, caid, provid, pid, count, n + 1, true); + add_emmfilter_to_list(demux_id, filt, caid, provid, pid, n + 1, true); } } else @@ -928,7 +926,7 @@ return 1; // all ok! } -void dvbapi_start_filter(int32_t demux_id, int32_t pidindex, uint16_t pid, uint16_t caid, uint32_t provid, uchar table, uchar mask, int32_t timeout, int32_t type, int32_t count) +void dvbapi_start_filter(int32_t demux_id, int32_t pidindex, uint16_t pid, uint16_t caid, uint32_t provid, uchar table, uchar mask, int32_t timeout, int32_t type) { uchar filter[32]; memset(filter, 0, 32); @@ -937,7 +935,7 @@ filter[16] = mask; cs_debug_mask(D_DVBAPI, "[DVBAPI] Demuxer #%d try to start new filter for caid: %04X, provid: %06X, pid: %04X", demux_id, caid, provid, pid); - dvbapi_set_filter(demux_id, selected_api, pid, caid, provid, filter, filter + 16, timeout, pidindex, count, type, 0); + dvbapi_set_filter(demux_id, selected_api, pid, caid, provid, filter, filter + 16, timeout, pidindex, type, 0); } static int32_t dvbapi_find_emmpid(int32_t demux_id, uint8_t type, uint16_t caid, uint32_t provid) @@ -947,28 +945,22 @@ for(k = 0; k < demux[demux_id].EMMpidcount; k++) { if(demux[demux_id].EMMpids[k].CAID == caid - && demux[demux_id].EMMpids[k].PROVID == provid && provid != 0 + && demux[demux_id].EMMpids[k].PROVID == provid && (demux[demux_id].EMMpids[k].type & type)) { return k; } - else if(demux[demux_id].EMMpids[k].CAID == caid - && (!demux[demux_id].EMMpids[k].PROVID || !provid) - && (demux[demux_id].EMMpids[k].type & type) && bck) - { bck = k; } } return bck; } -int32_t dvbapi_start_emm_filter(int32_t demux_index) +void dvbapi_start_emm_filter(int32_t demux_index) { - unsigned int j, fcount = 0, fcount_added = 0; - const char *typtext[] = { "UNIQUE", "SHARED", "GLOBAL", "UNKNOWN" }; - + unsigned int j; + if(!demux[demux_index].EMMpidcount) - { return 0; } - fcount = demux[demux_index].emm_filter; + { return; } //if (demux[demux_index].emm_filter) - // return 0; + // return; struct s_csystem_emm_filter *dmx_filter = NULL; @@ -978,7 +970,7 @@ struct s_reader *rdr = NULL; struct s_client *cl = cur_client(); if(!cl || !cl->aureader_list) - { return 0; } + { return; } LL_ITER itr = ll_iter_create(cl->aureader_list); while((rdr = ll_iter_next(&itr))) @@ -987,135 +979,83 @@ if(!rdr->client || rdr->audisabled != 0 || !rdr->enable || (!is_network_reader(rdr) && rdr->card_status != CARD_INSERTED)) { continue; } - caid = ncaid = rdr->caid; - struct s_cardsystem *cs; - if(!rdr->caid) - { cs = get_cardsystem_by_caid(rdr->csystem.caids[0]); } //Bulcrypt - else - { cs = get_cardsystem_by_caid(rdr->caid); } - - if(cs) + uint16_t c; + for(c = 0; c < demux[demux_index].EMMpidcount; c++) { - if(chk_is_betatunnel_caid(rdr->caid) == 1) - { ncaid = tunemm_caid_map(TO_FROM, rdr->caid, demux[demux_index].program_number); } - if(rdr->caid != ncaid && dvbapi_find_emmpid(demux_index, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL, ncaid, 0) > -1) - { - cs->get_tunemm_filter(rdr, &dmx_filter, &filter_count); - caid = ncaid; - cs_debug_mask(D_DVBAPI, "[EMM Filter] setting emm filter for betatunnel: %04X -> %04X", caid, rdr->caid); - } - else if (cs->get_emm_filter) - { - cs->get_emm_filter(rdr, &dmx_filter, &filter_count); - } - } - else - { - cs_debug_mask(D_DVBAPI, "[EMM Filter] cardsystem for emm filter for %s not found", rdr->label); - continue; - } - - for(j = 0; j < filter_count ; j++) - { - if(dmx_filter[j].enabled == 0) - { continue; } - - uchar filter[32]; - memset(filter, 0, sizeof(filter)); // reset filter - uint32_t usefilterbytes = 16; // default use all filters - memcpy(filter, dmx_filter[j].filter, usefilterbytes); - memcpy(filter + 16, dmx_filter[j].mask, usefilterbytes); - int32_t emmtype = dmx_filter[j].type; - int32_t l = -1; - - if((filter[0] && (((1 << (filter[0] % 0x80)) & rdr->b_nano) && !((1 << (filter[0] % 0x80)) & rdr->s_nano)))) - { continue; } - - if((rdr->blockemm & emmtype) && !(((1 << (filter[0] % 0x80)) & rdr->s_nano) || (rdr->saveemm & emmtype))) - { continue; } - - if(rdr->caid == 0x100) - { - uint32_t seca_provid = 0; - if(emmtype == EMM_SHARED) - { seca_provid = b2i(2, filter + 1); } - l = dvbapi_find_emmpid(demux_index, emmtype, 0x0100, seca_provid); - } - else - { - // provid 0 is safe since oscam sets filter with e.g. rdr->sa & doesn't add filter twice (is_emmfilter_in_list) - if(!rdr->caid) - { - l = dvbapi_find_emmpid(demux_index, emmtype, rdr->csystem.caids[0], 0); //Bulcrypt - if(l < 0) - { l = dvbapi_find_emmpid(demux_index, emmtype, rdr->csystem.caids[1], 0); } - } - else - { - if(rdr->auprovid) + caid = ncaid = demux[demux_index].EMMpids[c].CAID; + if(!caid) continue; + if(emm_reader_match(rdr, caid, 0)) + { + cs = get_cardsystem_by_caid(caid); + if(cs) + { + if(chk_is_betatunnel_caid(caid) == 1) + { + ncaid = tunemm_caid_map(TO_FROM, caid, demux[demux_index].program_number); + } + if(caid != ncaid && dvbapi_find_emmpid(demux_index, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL, ncaid, 0) > -1) { - l = dvbapi_find_emmpid(demux_index, emmtype, caid, rdr->auprovid); - if(l < 0) - { l = dvbapi_find_emmpid(demux_index, emmtype, caid, 0); } + cs->get_tunemm_filter(rdr, &dmx_filter, &filter_count); + cs_debug_mask(D_DVBAPI, "[EMM Filter] setting emm filter for betatunnel: %04X -> %04X", ncaid, caid); + caid = ncaid; } - else + else if (cs->get_emm_filter) { - l = dvbapi_find_emmpid(demux_index, emmtype, caid, 0); + cs->get_emm_filter(rdr, &dmx_filter, &filter_count); } } - } - if(l > -1) - { - //filter already in list? - if(is_emmfilter_in_list(filter, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].PROVID)) + else { - fcount_added++; + cs_debug_mask(D_DVBAPI, "[EMM Filter] cardsystem for emm filter for caid %04X of reader %s not found", caid, rdr->label); continue; } - uint32_t typtext_idx = 0; - int32_t ret = -1; - while(((emmtype >> typtext_idx) & 0x01) == 0 && typtext_idx < sizeof(typtext) / sizeof(const char *)) + for(j = 0; j < filter_count ; j++) { - ++typtext_idx; - } + if(dmx_filter[j].enabled == 0) + { continue; } - cs_ddump_mask(D_DVBAPI, filter, 32, "[EMM Filter] starting emm filter type %s, pid: 0x%04X", typtext[typtext_idx], demux[demux_index].EMMpids[l].PID); - fcount++; // increase total number of emmfilters - if(fcount > demux[demux_index].max_emm_filter) - { - add_emmfilter_to_list(demux_index, filter, demux[demux_index].EMMpids[l].CAID, demux[demux_index].EMMpids[l].PROVID, demux[demux_index].EMMpids[l].PID, fcount, 0, false); - } - else - { - ret = dvbapi_set_filter(demux_index, selected_api, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].CAID, - demux[demux_index].EMMpids[l].PROVID, filter, filter + 16, 0, demux[demux_index].pidindex, fcount, TYPE_EMM, 1); - } - if(ret != -1) - { - demux[demux_index].emm_filter++; // increase total active filters - } - else // not set successful, so add it to the list for try again later on! - { - add_emmfilter_to_list(demux_index, filter, demux[demux_index].EMMpids[l].CAID, demux[demux_index].EMMpids[l].PROVID, demux[demux_index].EMMpids[l].PID, fcount, 0, false); + uchar filter[32]; + memset(filter, 0, sizeof(filter)); // reset filter + uint32_t usefilterbytes = 16; // default use all filters + memcpy(filter, dmx_filter[j].filter, usefilterbytes); + memcpy(filter + 16, dmx_filter[j].mask, usefilterbytes); + int32_t emmtype = dmx_filter[j].type; + int32_t l = -1; + + if((filter[0] && (((1 << (filter[0] % 0x80)) & rdr->b_nano) && !((1 << (filter[0] % 0x80)) & rdr->s_nano)))) + { continue; } + + if((rdr->blockemm & emmtype) && !(((1 << (filter[0] % 0x80)) & rdr->s_nano) || (rdr->saveemm & emmtype))) + { continue; } + + if(caid == 0x100) + { + uint32_t seca_provid = 0; + if(emmtype == EMM_SHARED) + { seca_provid = b2i(2, filter + 1); } + l = dvbapi_find_emmpid(demux_index, emmtype, 0x0100, seca_provid); + check_add_emmpid(demux_index, filter, l, emmtype); + } + else + { + if(rdr->auprovid) + { + l = dvbapi_find_emmpid(demux_index, emmtype, caid, rdr->auprovid); //check specific auprovid + check_add_emmpid(demux_index, filter, l, emmtype); + } + l = dvbapi_find_emmpid(demux_index, emmtype, caid, 0); //check generic for all provids (provid 000000) + check_add_emmpid(demux_index, filter, l, emmtype); + } } + + // dmx_filter not use below this point + NULLFREE(dmx_filter); } } - // dmx_filter not use below this point - NULLFREE(dmx_filter); } - - if(fcount) - { cs_debug_mask(D_DVBAPI, "[EMM Filter] %i matching emm filter found", fcount); } - if(fcount_added) - { - demux[demux_index].emm_filter=1; // mark as active - cs_debug_mask(D_DVBAPI, "[EMM Filter] %i matching emm filter skipped because they are already active on same emmpid:provid", fcount_added); - } - if(!fcount) { return 2; } - if(fcount == (unsigned int)abs(demux[demux_index].emm_filter)) { return 0; } - else { return 1; } + cs_debug_mask(D_DVBAPI, "[EMM Filter] %i activated emm filters", demux[demux_index].emm_filter); } void dvbapi_add_ecmpid_int(int32_t demux_id, uint16_t caid, uint16_t ecmpid, uint32_t provid) @@ -1608,7 +1548,7 @@ demux[demux_id].curindex = pid; // set current pid to the fresh started one dvbapi_start_filter(demux_id, pid, demux[demux_id].ECMpids[pid].ECM_PID, demux[demux_id].ECMpids[pid].CAID, - demux[demux_id].ECMpids[pid].PROVID, 0x80, 0xF0, 3000, TYPE_ECM, 0); + demux[demux_id].ECMpids[pid].PROVID, 0x80, 0xF0, 3000, TYPE_ECM); started = 1; request_cw(dvbapi_client, er, demux_id, 0); // do not register ecm since this try! @@ -1639,7 +1579,7 @@ demux[demux_id].curindex = pid; // set current pid to the fresh started one dvbapi_start_filter(demux_id, pid, demux[demux_id].ECMpids[pid].ECM_PID, demux[demux_id].ECMpids[pid].CAID, - demux[demux_id].ECMpids[pid].PROVID, 0x80, 0xF0, 3000, TYPE_ECM, 0); + demux[demux_id].ECMpids[pid].PROVID, 0x80, 0xF0, 3000, TYPE_ECM); started = 1; break; // we started an ecmfilter so stop looking for next matching reader! } @@ -1720,7 +1660,7 @@ if(!filter) { - cs_debug_mask(D_DVBAPI, "[DVBAPI] Demuxer #%d Filter #%d no filter matches -> SKIP!", demux_index, filter_num + 1); + cs_debug_mask(D_DVBAPI, "[DVBAPI] Demuxer #%d Filter #%d no filter matches -> SKIP!", demux_index, filter_num +1); return; } @@ -2829,7 +2769,7 @@ if(cfg.dvbapi_au > 0 && demux[demux_id].emmstart.time == 1) // irdeto fetch emm cat direct! { cs_ftime(&demux[demux_id].emmstart); // trick to let emm fetching start after 30 seconds to speed up zapping - dvbapi_start_filter(demux_id, demux[demux_id].pidindex, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM, 1); //CAT + dvbapi_start_filter(demux_id, demux[demux_id].pidindex, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM); //CAT } else { cs_ftime(&demux[demux_id].emmstart); } // for all other caids delayed start! @@ -3502,12 +3442,11 @@ if(!forceentry || (forceentry && !forceentry->force)) { - cs_debug_mask(D_DVBAPI, "[EMM Filter] removing emm filter %i num %i on demux index %i", - filter_item->count, filter_item->num, filter_item->demux_id); + cs_debug_mask(D_DVBAPI, "[EMM Filter] removing emm filter #%i on demux index %i", filter_item->num, filter_item->demux_id); dvbapi_stop_filternum(filter_item->demux_id, filter_item->num - 1); ll_iter_remove_data(&itr); add_emmfilter_to_list(filter_item->demux_id, filter_item->filter, filter_item->caid, - filter_item->provid, filter_item->pid, filter_item->count, -1, false); + filter_item->provid, filter_item->pid, -1, false); stopped++; } } @@ -3520,11 +3459,10 @@ while((filter_item2 = ll_iter_next(&itr2))) { - cs_ddump_mask(D_DVBAPI, filter_item2->filter, 32, "[EMM Filter] starting emm filter %i, pid: 0x%04X on demux index %i", - filter_item2->count, filter_item2->pid, filter_item2->demux_id); + cs_ddump_mask(D_DVBAPI, filter_item2->filter, 32, "[EMM Filter] starting emm filter pid: 0x%04X on demux index %i", filter_item2->pid, filter_item2->demux_id); ret = dvbapi_set_filter(filter_item2->demux_id, selected_api, filter_item2->pid, filter_item2->caid, filter_item2->provid, filter_item2->filter, filter_item2->filter + 16, 0, - demux[filter_item2->demux_id].pidindex, filter_item2->count, TYPE_EMM, 1); + demux[filter_item2->demux_id].pidindex, TYPE_EMM, 1); if(ret != -1) { ll_iter_remove_data(&itr2); @@ -3539,8 +3477,7 @@ while((filter_item = ll_iter_next(&itr))) { - add_emmfilter_to_list(filter_item->demux_id, filter_item->filter, filter_item->caid, - filter_item->provid, filter_item->pid, filter_item->count, 0, false); + add_emmfilter_to_list(filter_item->demux_id, filter_item->filter, filter_item->caid, filter_item->provid, filter_item->pid, 0, false); ll_iter_remove_data(&itr); } } @@ -3743,19 +3680,19 @@ int32_t gone = comp_timeb(&now, &demux[i].emmstart); if(gone > 30*1000){ cs_ftime(&demux[i].emmstart); // trick to let emm fetching start after 30 seconds to speed up zapping - dvbapi_start_filter(i, demux[i].pidindex, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM, 1); //CAT + dvbapi_start_filter(i, demux[i].pidindex, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM); //CAT } //continue; // proceed with next demuxer } //early start for irdeto since they need emm before ecm (pmt emmstart = 1 if detected caid 0x06) - int32_t emmstarted = 0; + int32_t emmstarted = demux[i].emm_filter; if(cfg.dvbapi_au && demux[i].EMMpidcount > 0) // check every time since share readers might give us new filters due to hexserial change { if(!emmcounter) { demux[i].emmstart = now; - emmstarted = dvbapi_start_emm_filter(i); // start emmfiltering if emmpids are found + dvbapi_start_emm_filter(i); // start emmfiltering if emmpids are found } else { @@ -3763,11 +3700,12 @@ if(gone > 30*1000) { demux[i].emmstart = now; - emmstarted = dvbapi_start_emm_filter(i); // start emmfiltering delayed if filters already were running + dvbapi_start_emm_filter(i); // start emmfiltering delayed if filters already were running } } - //if(emmstarted == 1 && !emmcounter) { continue; } // proceed with next demuxer if no emms where running before - if(emmstarted == 2) { demux[i].EMMpidcount = 0; } // if no emm filters applied reset emmpidcount (fixes repeated trying of setting filters!) + if(emmstarted != demux[i].emm_filter && !emmcounter) { continue; } // proceed with next demuxer if no emms where running before + // if no additional filters activated reset emmpidcount (fixes repeated trying of setting filters!) + if(emmstarted == demux[i].emm_filter) { demux[i].EMMpidcount = 0; } } if(ecmcounter == 0 && demux[i].ECMpidcount > 0) // Restart decoding all caids we have ecmpids but no ecm filters! @@ -4539,7 +4477,7 @@ if(er->selected_reader) { fprintf(ecmtxt, "reader: %s\n", er->selected_reader->label); - if(is_cascading_reader(er->selected_reader)) + if(is_network_reader(er->selected_reader)) { fprintf(ecmtxt, "from: %s\n", er->selected_reader->device); } else { fprintf(ecmtxt, "from: local\n"); } @@ -5014,6 +4952,48 @@ return client_name; } +void check_add_emmpid(int32_t demux_index, uchar *filter, int32_t l, int32_t emmtype) +{ + if (l<0) return; + + //filter already in list? + if(is_emmfilter_in_list(filter, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].PROVID)) + { + return; + } + + uint32_t typtext_idx = 0; + int32_t ret = -1; + const char *typtext[] = { "UNIQUE", "SHARED", "GLOBAL", "UNKNOWN" }; + + while(((emmtype >> typtext_idx) & 0x01) == 0 && typtext_idx < sizeof(typtext) / sizeof(const char *)) + { + ++typtext_idx; + } + + if(demux[demux_index].emm_filter >= demux[demux_index].max_emm_filter) // can this filter be started? if not add to list of inactive emmfilters + { + add_emmfilter_to_list(demux_index, filter, demux[demux_index].EMMpids[l].CAID, demux[demux_index].EMMpids[l].PROVID, demux[demux_index].EMMpids[l].PID, 0, false); + } + else // activate this emmfilter + { + ret = dvbapi_set_filter(demux_index, selected_api, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].CAID, + demux[demux_index].EMMpids[l].PROVID, filter, filter + 16, 0, demux[demux_index].pidindex, TYPE_EMM, 1); + } + if(ret != -1) + { + demux[demux_index].emm_filter++; // increase total active filters + cs_ddump_mask(D_DVBAPI, filter, 32, "[EMM Filter] started emm filter type %s, pid: 0x%04X", typtext[typtext_idx], demux[demux_index].EMMpids[l].PID); + return; + } + else // not set successful, so add it to the list for try again later on! + { + add_emmfilter_to_list(demux_index, filter, demux[demux_index].EMMpids[l].CAID, demux[demux_index].EMMpids[l].PROVID, demux[demux_index].EMMpids[l].PID, 0, false); + cs_ddump_mask(D_DVBAPI, filter, 32, "[EMM Filter] added inactive emm filter type %s, pid: 0x%04X", typtext[typtext_idx], demux[demux_index].EMMpids[l].PID); + } + return; +} + uint16_t dvbapi_get_client_proto_version(void) { return client_proto_version; diff -Nru oscam-1.20-10210~r9982/module-dvbapi.h oscam-1.20-10217~r9989/module-dvbapi.h --- oscam-1.20-10210~r9982/module-dvbapi.h 2014-11-05 22:24:19.000000000 +0000 +++ oscam-1.20-10217~r9989/module-dvbapi.h 2014-11-08 16:02:27.000000000 +0000 @@ -284,6 +284,7 @@ const char *dvbapi_get_client_name(void); uint16_t dvbapi_get_client_proto_version(void); void delayer(ECM_REQUEST *er); +void check_add_emmpid(int32_t demux_index, uchar *filter, int32_t l, int32_t emmtype); #ifdef DVBAPI_LOG_PREFIX #undef cs_log diff -Nru oscam-1.20-10210~r9982/oscam-ecm.c oscam-1.20-10217~r9989/oscam-ecm.c --- oscam-1.20-10210~r9982/oscam-ecm.c 2014-11-05 22:24:19.000000000 +0000 +++ oscam-1.20-10217~r9989/oscam-ecm.c 2014-11-08 16:02:27.000000000 +0000 @@ -1251,7 +1251,7 @@ ESC: - if(er->rc == E_TIMEOUT) // cleanout timeout ecm response so they can be asked again + if(er->rc == E_TIMEOUT || er->rc == E_NOTFOUND) // cleanout timeout and notfound ecm response so they can be asked again { struct s_ecm_answer *ea_list; for(ea_list = er->matching_rdr; ea_list; ea_list = ea_list->next) diff -Nru oscam-1.20-10210~r9982/oscam-emm.c oscam-1.20-10217~r9989/oscam-emm.c --- oscam-1.20-10210~r9982/oscam-emm.c 2014-11-05 22:24:19.000000000 +0000 +++ oscam-1.20-10217~r9989/oscam-emm.c 2014-11-08 16:02:27.000000000 +0000 @@ -8,6 +8,7 @@ #include "oscam-time.h" #include "oscam-work.h" #include "reader-common.h" +#include "oscam-chk.h" const char *entitlement_type[] = { "", "package", "PPV-Event", "chid", "tier", "class", "PBM", "admin" }; @@ -97,7 +98,7 @@ char *rtxt[] = { "error", - is_cascading_reader(reader) ? "sent" : "written", + is_network_reader(reader) ? "sent" : "written", "skipped", "blocked" }; @@ -171,7 +172,7 @@ int caid_found = 0; for(i = 0; i < (int)ARRAY_SIZE(reader->csystem.caids); i++) { - if(reader->csystem.caids[i] == caid) + if(reader->csystem.caids[i] == caid || chk_ctab_ex(caid, &reader->ctab)) { caid_found = 1; break; @@ -367,7 +368,7 @@ struct s_cardsystem *cs = NULL; - if(is_cascading_reader(aureader)) // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM) + if(is_network_reader(aureader)) // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM) { if(!aureader->ph.c_send_emm) // no emm support { continue; } @@ -460,7 +461,7 @@ is_blocked = (aureader->blockemm & EMM_GLOBAL) == EMM_GLOBAL; break; } - + // if not already blocked we check for block by len if(!is_blocked) { is_blocked = cs_emmlen_is_blocked(aureader, ep->emm[2]) ; } @@ -584,7 +585,7 @@ // Ecs=2 skip if((rc = ecs) < 2) { - if(is_cascading_reader(reader)) + if(is_network_reader(reader)) { rdr_debug_mask(reader, D_READER, "network emm reader"); if(reader->ph.c_send_emm)