Changeset 6519
- Timestamp:
- 03/14/12 18:00:35 (12 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/module-dvbapi.c
r6509 r6519 22 22 DEMUXTYPE demux[MAX_DEMUX]; 23 23 int32_t ca_fd[8]; 24 LLIST *channel_cache;25 24 26 25 struct s_dvbapi_priority *dvbapi_priority=NULL; … … 33 32 #endif 34 33 35 struct s_channel_cache { 36 uint16_t caid; 37 uint32_t prid; 38 uint16_t srvid; 39 uint16_t pid; 40 int8_t chid; 41 } CHANNEL_CACHE; 42 43 struct s_channel_cache *find_channel_cache(int32_t demux_id, int32_t pidindex) 44 { 45 struct s_ecmpids *p = &demux[demux_id].ECMpids[pidindex]; 46 struct s_channel_cache *c; 47 LL_ITER it; 48 49 if (!channel_cache) 50 channel_cache = ll_create("channel cache"); 51 52 it = ll_iter_create(channel_cache); 53 while ((c=ll_iter_next(&it))) { 54 if (demux[demux_id].program_number == c->srvid && 55 p->CAID == c->caid && 56 p->ECM_PID == c->pid && 57 p->PROVID == c->prid && 58 p->irdeto_curchid == c->chid) { 59 cs_debug_mask(D_DVBAPI, "found in channel cache: %4X:%6X:%4X:%4X:%4X", c->caid, c->prid, c->srvid, c->pid, c->chid); 60 return c; 61 } 62 } 63 return NULL; 64 } 65 66 int32_t edit_channel_cache(int32_t demux_id, int32_t pidindex, uint8_t add) 67 { 68 struct s_ecmpids *p = &demux[demux_id].ECMpids[pidindex]; 69 struct s_channel_cache *c; 70 LL_ITER it; 71 int32_t count = 0; 72 73 if (!channel_cache) 74 channel_cache = ll_create("channel cache"); 75 76 it = ll_iter_create(channel_cache); 77 while ((c=ll_iter_next(&it))) { 78 if (demux[demux_id].program_number == c->srvid && 79 p->CAID == c->caid && 80 p->ECM_PID == c->pid && 81 p->PROVID == c->prid && 82 p->irdeto_curchid == c->chid) { 83 if (add) 84 return 0; //already added 85 ll_iter_remove_data(&it); 86 count++; 87 } 88 } 89 90 if (add) { 91 c = cs_malloc(&c, sizeof(struct s_channel_cache), 0); 92 c->srvid = demux[demux_id].program_number; 93 c->caid = p->CAID; 94 c->pid = p->ECM_PID; 95 c->prid = p->PROVID; 96 c->chid = p->irdeto_curchid; 97 ll_append(channel_cache, c); 98 cs_debug_mask(D_DVBAPI, "added to channel cache: %4X:%6X:%4X:%4X:%4X", c->caid, c->prid, c->srvid, c->pid, c->chid); 99 count++; 100 } 101 102 return count; 103 } 104 105 106 107 int32_t dvbapi_set_filter(int32_t demux_id, int32_t api, uint16_t pid, uchar *filt, uchar *mask, int32_t timeout, int32_t pidindex, int32_t count, int32_t type) { 34 int32_t dvbapi_set_filter(int32_t demux_id, int32_t api, uint16_t pid, uint16_t caid, uchar *filt, uchar *mask, int32_t timeout, int32_t pidindex, int32_t count, int32_t type) { 108 35 #ifdef AZBOX 109 36 openxcas_caid = demux[demux_id].ECMpids[pidindex].CAID; … … 124 51 demux[demux_id].demux_fd[n].pidindex = pidindex; 125 52 demux[demux_id].demux_fd[n].pid = pid; 53 demux[demux_id].demux_fd[n].caid = caid; 126 54 demux[demux_id].demux_fd[n].type = type; 127 55 demux[demux_id].demux_fd[n].count = count; … … 228 156 filter[16]=0xFF; 229 157 230 ret = dvbapi_set_filter(0, selected_api, 0x0001, filter, filter+16, 1, 0, 0, TYPE_ECM);158 ret = dvbapi_set_filter(0, selected_api, 0x0001, 0x0001, filter, filter+16, 1, 0, 0, TYPE_ECM); 231 159 if (ret >= 0) dvbapi_stop_filter(0, TYPE_ECM); 232 160 else return 0; … … 352 280 } 353 281 354 void dvbapi_start_filter(int32_t demux_id, int32_t pidindex, uint16_t pid, u char table, uchar mask, int32_t timeout, int32_t type, int32_t count)282 void dvbapi_start_filter(int32_t demux_id, int32_t pidindex, uint16_t pid, uint16_t caid, uchar table, uchar mask, int32_t timeout, int32_t type, int32_t count) 355 283 { 356 284 uchar filter[32]; … … 363 291 filter[16]=mask; 364 292 365 dvbapi_set_filter(demux_id, selected_api, pid, filter, filter+16, timeout, pidindex, count, type);293 dvbapi_set_filter(demux_id, selected_api, pid, caid, filter, filter+16, timeout, pidindex, count, type); 366 294 } 367 295 … … 472 400 473 401 cs_ddump_mask(D_DVBAPI, filter, 32, "starting emm filter type %s, pid: 0x%04X", typtext[typtext_idx], demux[demux_index].EMMpids[l].PID); 474 dvbapi_set_filter(demux_index, selected_api, demux[demux_index].EMMpids[l].PID, filter, filter+16, 0, demux[demux_index].pidindex, count, TYPE_EMM);402 dvbapi_set_filter(demux_index, selected_api, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].CAID, filter, filter+16, 0, demux[demux_index].pidindex, count, TYPE_EMM); 475 403 } else { 476 404 cs_debug_mask(D_DVBAPI, "no emm pid found"); … … 677 605 int32_t streamcount=0; 678 606 679 int32_t last_pidindex = demux[demux_id].pidindex;680 607 demux[demux_id].pidindex = demux[demux_id].curindex; 681 608 682 for (j=0; j<demux[demux_id].ECMpidcount; j++) {609 for (j=0; j<demux[demux_id].ECMpidcount; j++) { 683 610 if (demux[demux_id].curindex == j || (demux[demux_id].ECMpids[demux[demux_id].curindex].CAID == demux[demux_id].ECMpids[j].CAID 684 611 && demux[demux_id].ECMpids[demux[demux_id].curindex].PROVID == demux[demux_id].ECMpids[j].PROVID … … 689 616 continue; 690 617 691 dvbapi_start_filter(demux_id, j, demux[demux_id].ECMpids[j].ECM_PID, 0x80, 0xF0, 3000, TYPE_ECM, 0);618 dvbapi_start_filter(demux_id, j, demux[demux_id].ECMpids[j].ECM_PID, demux[demux_id].ECMpids[j].CAID, 0x80, 0xF0, 3000, TYPE_ECM, 0); 692 619 } 693 620 … … 713 640 cs_log("Start descrambling PID #%d (CAID: %04X) %d", demux[demux_id].curindex, demux[demux_id].ECMpids[demux[demux_id].curindex].CAID, streamcount); 714 641 715 if (cfg.dvbapi_au>0 && last_pidindex != demux[demux_id].pidindex) { 716 if (last_pidindex != -1) 717 dvbapi_stop_filter(demux_id, TYPE_EMM); 718 dvbapi_start_filter(demux_id, demux[demux_id].pidindex, 0x001, 0x01, 0xFF, 0, TYPE_EMM, 0); //CAT 719 } 642 if (cfg.dvbapi_au>0) 643 dvbapi_start_filter(demux_id, demux[demux_id].pidindex, 0x001, 0x001, 0x01, 0xFF, 0, TYPE_EMM, 0); //CAT 720 644 } 721 645 … … 969 893 970 894 void dvbapi_resort_ecmpids(int32_t demux_index) { 971 int32_t n,i ,found;895 int32_t n,i; 972 896 973 897 for (n=0; n<demux[demux_index].ECMpidcount; n++) … … 976 900 demux[demux_index].max_status=0; 977 901 int32_t new_status = demux[demux_index].ECMpidcount; // reverse order! 978 979 found = -1;980 for (n = 0; n < demux[demux_index].ECMpidcount; n++) {981 if (find_channel_cache(demux_index, n)) {982 found = n;983 break;984 }985 }986 if (found != -1) { //Found in cache987 for (n = 0; n < demux[demux_index].ECMpidcount; n++) {988 if (n != found)989 demux[demux_index].ECMpids[n].status = -1;990 else991 demux[demux_index].ECMpids[n].status = 1;992 }993 demux[demux_index].max_status = 1;994 return;995 }996 997 902 998 903 if (dvbapi_priority) { … … 1009 914 1010 915 if (p->type=='p') { 1011 demux[demux_index].ECMpids[n].status = new_status--; 1012 cs_debug_mask(D_DVBAPI, "[PRIORITIZE PID %d] %04X:%06X (position: %d)", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].status); 916 917 if (cfg.preferlocalcards) { //prefer caids from local readers: 918 struct s_reader *rdr; 919 ECM_REQUEST *er = cs_malloc(&er, sizeof(ECM_REQUEST), 0); 920 921 for (n=0; n<demux[demux_index].ECMpidcount; n++) { 922 if (demux[demux_index].ECMpids[n].status == -1) //ignore 923 continue; 924 er->caid = demux[demux_index].ECMpids[n].CAID; 925 er->prid = demux[demux_index].ECMpids[n].PROVID; 926 er->pid = demux[demux_index].ECMpids[n].ECM_PID; 927 er->srvid = demux[demux_index].program_number; 928 er->client = cur_client(); 929 930 LL_ITER it = ll_iter_create(configured_readers); 931 while ((rdr=ll_iter_next(&it))) { 932 if (rdr->enable && !(rdr->typ & R_IS_NETWORK) && rdr->card_status==CARD_INSERTED) { //local reader 933 if (matching_reader(er, rdr)) { 934 demux[demux_index].ECMpids[n].status = new_status--; //priority 935 cs_debug_mask(D_DVBAPI, "[PRIORITIZE PID %d] %04X:%06X (localrdr: %s position: %d)", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, rdr->label, demux[demux_index].ECMpids[n].status); 936 break; 937 } 938 } 939 } 940 } 941 free(er); 942 } else { 943 demux[demux_index].ECMpids[n].status = new_status--; 944 cs_debug_mask(D_DVBAPI, "[PRIORITIZE PID %d] %04X:%06X (position: %d)", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].status); 945 } 1013 946 } else if (p->type=='i') { 1014 947 if (p->chid) continue; … … 1044 977 } 1045 978 1046 //prefer caids from local readers:1047 if (cfg.preferlocalcards) {1048 struct s_reader *rdr;1049 ECM_REQUEST *er = cs_malloc(&er, sizeof(ECM_REQUEST), 0);1050 1051 for (n=demux[demux_index].ECMpidcount; n>-1; n--) { //maintain pid prio order of the pmt.1052 if (demux[demux_index].ECMpids[n].status == -1) //ignore1053 continue;1054 er->caid = demux[demux_index].ECMpids[n].CAID;1055 er->prid = demux[demux_index].ECMpids[n].PROVID;1056 er->pid = demux[demux_index].ECMpids[n].ECM_PID;1057 er->srvid = demux[demux_index].program_number;1058 er->client = cur_client();1059 1060 LL_ITER it = ll_iter_create(configured_readers);1061 while ((rdr=ll_iter_next(&it))) {1062 if (rdr->enable && !(rdr->typ & R_IS_NETWORK) && rdr->card_status==CARD_INSERTED) { //local reader1063 if (matching_reader(er, rdr)) {1064 demux[demux_index].ECMpids[n].status = new_status++; //priority1065 cs_debug_mask(D_DVBAPI, "[PRIORITIZE PID %d] %04X:%06X (localrdr: %s position: %d)", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, rdr->label, demux[demux_index].ECMpids[n].status);1066 break;1067 }1068 }1069 }1070 }1071 free(er);1072 }1073 1074 979 demux[demux_index].max_status = new_status; 1075 980 return; … … 1124 1029 } 1125 1030 1126 static voidrequest_cw(struct s_client *dvbapi_client, ECM_REQUEST *er)1031 static int8_t request_cw(struct s_client *dvbapi_client, ECM_REQUEST *er) 1127 1032 { 1033 #ifdef WITH_LB 1034 int8_t do_request = 1; 1035 if (cfg.lb_mode) { 1036 READER_STAT *stat = get_fastest_stat(er->caid, er->prid, er->srvid, er->chid, er->l); 1037 if (stat && stat->rc >= E_NOTFOUND) { 1038 do_request = 0; 1039 } 1040 } 1041 1042 if (do_request) { 1043 cs_debug_mask(D_DVBAPI, "request cw for caid %04X provid %06X srvid %04X pid %04X chid %04X", er->caid, er->prid, er->srvid, er->pid, er->chid); 1044 get_cw(dvbapi_client, er); 1045 } 1046 else { 1047 cs_debug_mask(D_DVBAPI, "request cw lb-ignored for caid %04X provid %06X srvid %04X pid %04X chid %04X", er->caid, er->prid, er->srvid, er->pid, er->chid); 1048 er->rc = E_NOTFOUND; 1049 dvbapi_send_dcw(dvbapi_client, er); 1050 free(er); 1051 } 1052 return do_request; 1053 #else 1128 1054 cs_debug_mask(D_DVBAPI, "request cw for caid %04X provid %06X srvid %04X pid %04X chid %04X", er->caid, er->prid, er->srvid, er->pid, er->chid); 1129 1055 get_cw(dvbapi_client, er); 1056 #endif 1130 1057 } 1131 1058 … … 1142 1069 int32_t start=1; 1143 1070 int32_t end=demux[demux_id].max_status; 1071 1144 1072 while (num==-1) { 1145 1073 for (j = end; j >= start && num == -1; j--) { //largest status first! … … 1219 1147 1220 1148 if (cfg.dvbapi_requestmode == 1) { 1221 dvbapi_start_filter(demux_id, num, demux[demux_id].ECMpids[num].ECM_PID, 0x80, 0xF0, 3000, TYPE_ECM, 3);1149 dvbapi_start_filter(demux_id, num, demux[demux_id].ECMpids[num].ECM_PID, demux[demux_id].ECMpids[num].CAID, 0x80, 0xF0, 3000, TYPE_ECM, 3); 1222 1150 dvbapi_try_next_caid(demux_id); 1223 1151 } else { 1224 dvbapi_start_filter(demux_id, num, demux[demux_id].ECMpids[num].ECM_PID, 0x80, 0xF0, 3000, TYPE_ECM, 0);1152 dvbapi_start_filter(demux_id, num, demux[demux_id].ECMpids[num].ECM_PID, demux[demux_id].ECMpids[num].CAID, 0x80, 0xF0, 3000, TYPE_ECM, 0); 1225 1153 } 1226 1154 } … … 1777 1705 int32_t num = demux[demux_id].curindex;//FIXME or pidindex ? 1778 1706 dvbapi_stop_filternum(demux_id, filter_num); 1779 dvbapi_start_filter(demux_id, num, demux[demux_id].ECMpids[num].ECM_PID, buffer[0] ^ 1, 0xFF, 3000, TYPE_ECM, 0);1707 dvbapi_start_filter(demux_id, num, demux[demux_id].ECMpids[num].ECM_PID, demux[demux_id].ECMpids[num].CAID, buffer[0] ^ 1, 0xFF, 3000, TYPE_ECM, 0); 1780 1708 #endif 1781 1709 … … 2064 1992 2065 1993 for (j=0; j<demux[i].ECMpidcount; j++) 2066 if ((demux[i].ECMpids[j].CAID == er->caid || demux[i].ECMpids[j].CAID == er->ocaid) && demux[i].ECMpids[j].ECM_PID == er->pid && demux[i].ECMpids[j].PROVID == er->prid)1994 if ((demux[i].ECMpids[j].CAID == er->caid || demux[i].ECMpids[j].CAID == er->ocaid) && demux[i].ECMpids[j].ECM_PID == er->pid) 2067 1995 break; 2068 1996 if (j==demux[i].ECMpidcount) continue; … … 2070 1998 if (er->rc < E_NOTFOUND && cfg.dvbapi_requestmode==0 && (demux[i].pidindex==-1) && er->caid!=0) { 2071 1999 dvbapi_start_descrambling(i); 2072 edit_channel_cache(i, j, 1);2073 2000 } 2074 2001 2075 2002 if (er->rc < E_NOTFOUND && cfg.dvbapi_requestmode==1 && er->caid!=0 && demux[i].ECMpids[j].checked != 2) { //FOUND 2076 2003 2077 int32_t num_pids = 0, last_idx = j; 2078 2079 int32_t t; 2080 for (t = 0; t < demux[i].ECMpidcount; t++) { 2081 2082 //check this FOUND for higher status: 2083 if (t != j 2084 && demux[i].ECMpids[j].status 2085 >= demux[i].ECMpids[t].status) { //mark index t as low status 2086 demux[i].ECMpids[t].checked = 2; 2087 } 2088 if (demux[i].ECMpids[t].checked != 2) { 2089 num_pids++; 2090 last_idx = t; 2091 } 2092 } 2093 2094 if (num_pids <= 1) { //Only one left, activate it: 2095 int32_t o; 2096 for (o = 0; o < MAX_FILTER; o++) { 2097 if (demux[i].demux_fd[o].fd > 0) { 2098 if (demux[i].demux_fd[o].pid 2099 == demux[i].ECMpids[last_idx].ECM_PID) 2100 demux[i].demux_fd[o].count = 0; //activate last_idx 2101 else 2102 dvbapi_stop_filternum(i, o); //drop other 2103 } 2104 } 2105 edit_channel_cache(i, j, 1); 2106 } 2107 2108 if (demux[i].pidindex == -1) { 2109 demux[i].curindex = j; 2110 dvbapi_start_descrambling(i); 2111 } else if (demux[i].curindex != j) { 2112 demux[i].curindex = j; 2113 //I hope this trick works for all: adjust the index to write the right cw: 2114 demux[i].ECMpids[j].index = 2115 demux[i].ECMpids[demux[i].pidindex].index; 2116 dvbapi_start_descrambling(i); 2117 } 2004 int32_t num_pids=0, last_idx=j; 2005 2006 int32_t t; 2007 for (t=0;t<demux[i].ECMpidcount;t++) { 2008 2009 //check this FOUND for higher status: 2010 if (t!=j && demux[i].ECMpids[j].status >= demux[i].ECMpids[t].status) { //mark index t as low status 2011 demux[i].ECMpids[t].checked = 2; 2012 } 2013 if (demux[i].ECMpids[t].checked != 2) { 2014 num_pids++; 2015 last_idx=t; 2016 } 2017 } 2018 2019 if (num_pids <= 1) { //Only one left, activate it: 2020 int32_t o; 2021 for (o = 0; o < MAX_FILTER; o++) { 2022 if (demux[i].demux_fd[o].fd > 0) { //FIXME: maybee ocaid for betatunnel needs to be added?! 2023 if ((demux[i].demux_fd[o].pid == demux[i].ECMpids[last_idx].ECM_PID) && (demux[i].demux_fd[o].caid == demux[i].ECMpids[last_idx].CAID )) 2024 demux[i].demux_fd[o].count = 0; //activate last_idx 2025 else 2026 dvbapi_stop_filternum(i, TYPE_ECM); //only drop ECMTYPE Filters 2027 } //otherwise no EMM updates for 0100:00006a 2028 } 2029 } 2030 2031 if (demux[i].pidindex==-1) { 2032 demux[i].curindex = j; 2033 dvbapi_start_descrambling(i); 2034 } else if (demux[i].curindex != j) { 2035 demux[i].curindex = j; 2036 //I hope this trick works for all: adjust the index to write the right cw: 2037 demux[i].ECMpids[j].index = demux[i].ECMpids[demux[i].pidindex].index; 2038 dvbapi_start_descrambling(i); 2039 } 2118 2040 } 2119 2041 2120 2042 if (er->rc >= E_NOTFOUND) { 2121 edit_channel_cache(i, j, 0);2122 2043 if ((er->caid >> 8) == 0x06 && demux[i].ECMpids[j].irdeto_chids < (((0xFFFF<<(demux[i].ECMpids[j].irdeto_numchids)) ^ 0xFFFF) & 0xFFFF)) { 2123 2044 demux[i].ECMpids[j].irdeto_curchid++; … … 2129 2050 demux[i].ECMpids[j].irdeto_curchid = 0; 2130 2051 demux[i].ECMpids[j].irdeto_cycle = 0; 2131 int8_t last_checked = demux[i].ECMpids[j].checked;2132 2052 demux[i].ECMpids[j].checked = 2; 2133 2053 … … 2160 2080 num_pids++; 2161 2081 } 2162 if (!num_pids && last_checked == 1) { // we had rc=E_FOUND, but now we get a NOT_FOUND? Try all caids again: 2163 for (t=0;t<demux[i].ECMpidcount;t++) 2164 demux[i].ECMpids[t].checked = 0; 2165 demux[i].tries = 3; 2166 dvbapi_try_next_caid(i); 2167 } 2082 if (num_pids < 1) 2083 dvbapi_try_next_caid(i); 2168 2084 } 2169 2085 } -
trunk/module-dvbapi.h
r6409 r6519 73 73 int32_t pidindex; 74 74 int32_t pid; 75 uint16_t caid; 75 76 uint16_t type; 76 77 int32_t count; -
trunk/module-stat.c
r6509 r6519 186 186 } 187 187 return prid; 188 } 189 190 /** 191 * returns the fastest statistics. Usefull to check if we have decoded it in the past 192 * 193 * returns NULL if no reader stat is found. 194 * could also return a stat with rc=4 or rc=5 if no best found stat is available 195 * 196 * But: This function does not check user groups or reader configuration! 197 **/ 198 199 READER_STAT *get_fastest_stat(uint16_t caid, uint32_t prid, uint16_t srvid, uint16_t chid, int16_t ecmlen) 200 { 201 READER_STAT *stat, *result = NULL, *result2 = NULL; 202 int32_t result_time = 0; 203 struct s_reader *rdr = first_active_reader; 204 while (rdr) { 205 stat = get_stat(rdr, caid, prid, srvid, chid, ecmlen); 206 if (stat && stat->rc == E_FOUND) {//only return "founds" 207 int32_t weight = rdr->lb_weight <= 0?100:rdr->lb_weight; 208 int32_t time = stat->time_avg*100/weight; 209 if (!result || time < result_time) { 210 result = stat; 211 result_time = time; 212 } 213 } 214 if (stat && (!result2 || stat->rc < result2->rc)) 215 result2 = stat; 216 rdr=rdr->next; 217 } 218 if (!result) 219 result = result2; //return not found/timeout stats if we found no 220 return result; 188 221 } 189 222
Note:
See TracChangeset
for help on using the changeset viewer.