- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / module-dvbapi-chancache.c
blobc69dd50fa91e1f83c7ada162ae5a527fbe99f718
1 #define MODULE_LOG_PREFIX "dvbapi"
3 #include "globals.h"
5 #ifdef HAVE_DVBAPI
7 #include "oscam-config.h"
8 #include "oscam-ecm.h"
9 #include "oscam-string.h"
10 #include "module-dvbapi.h"
11 #include "module-dvbapi-chancache.h"
13 extern DEMUXTYPE demux[MAX_DEMUX];
15 static LLIST *channel_cache;
17 void dvbapi_save_channel_cache(void)
19 if(boxtype_is("dbox2")) return; // dont save channelcache on these boxes, they lack resources and will crash!
21 if (USE_OPENXCAS) // Why?
22 return;
24 char fname[256];
25 int32_t result = 0;
26 get_config_filename(fname, sizeof(fname), "oscam.ccache");
27 FILE *file = fopen(fname, "w");
29 if(!file)
31 cs_log("dvbapi channelcache can't write to file %s", fname);
32 return;
35 LL_ITER it = ll_iter_create(channel_cache);
36 struct s_channel_cache *c;
37 while((c = ll_iter_next(&it)))
39 result = fprintf(file, "%04X,%06X,%04X,%04X,%06X\n", c->caid, c->prid, c->srvid, c->pid, c->chid);
40 if(result < 0)
42 fclose(file);
43 result = remove(fname);
44 if(!result)
46 cs_log("error writing cache -> cache file removed!");
48 else
50 cs_log("error writing cache -> cache file could not be removed either!");
52 return;
56 fclose(file);
57 cs_log("dvbapi channelcache saved to %s", fname);
60 void dvbapi_load_channel_cache(void)
62 if(boxtype_is("dbox2")) return; // dont load channelcache on these boxes, they lack resources and will crash!
64 if (USE_OPENXCAS) // Why?
65 return;
67 char fname[256];
68 char line[1024];
69 FILE *file;
70 struct s_channel_cache *c;
72 get_config_filename(fname, sizeof(fname), "oscam.ccache");
73 file = fopen(fname, "r");
74 if(!file)
76 cs_log_dbg(D_TRACE, "dvbapi channelcache can't read from file %s", fname);
77 return;
80 int32_t i = 1;
81 int32_t valid = 0;
82 char *ptr, *saveptr1 = NULL;
83 char *split[6];
85 memset(line, 0, sizeof(line));
86 while(fgets(line, sizeof(line), file))
88 if(!line[0] || line[0] == '#' || line[0] == ';')
89 { continue; }
91 for(i = 0, ptr = strtok_r(line, ",", &saveptr1); ptr && i < 6 ; ptr = strtok_r(NULL, ",", &saveptr1), i++)
93 split[i] = ptr;
96 valid = (i == 5);
97 if(valid)
99 if(!cs_malloc(&c, sizeof(struct s_channel_cache)))
100 { continue; }
101 c->caid = a2i(split[0], 4);
102 c->prid = a2i(split[1], 6);
103 c->srvid = a2i(split[2], 4);
104 c->pid = a2i(split[3], 4);
105 c->chid = a2i(split[4], 6);
107 if(valid && c->caid != 0)
109 if(!channel_cache)
111 channel_cache = ll_create("channel cache");
114 ll_append(channel_cache, c);
116 else
118 NULLFREE(c);
122 fclose(file);
123 cs_log("dvbapi channelcache loaded from %s", fname);
126 struct s_channel_cache *dvbapi_find_channel_cache(int32_t demux_id, int32_t pidindex, int8_t caid_and_prid_only)
128 struct s_ecmpid *p = &demux[demux_id].ECMpids[pidindex];
129 struct s_channel_cache *c;
130 LL_ITER it;
132 if(!channel_cache)
133 { channel_cache = ll_create("channel cache"); }
135 it = ll_iter_create(channel_cache);
136 while((c = ll_iter_next(&it)))
139 if(caid_and_prid_only)
141 if(p->CAID == c->caid && (p->PROVID == c->prid || p->PROVID == 0)) // PROVID ==0 some provider no provid in PMT table
142 { return c; }
144 else
146 if(demux[demux_id].program_number == c->srvid
147 && p->CAID == c->caid
148 && p->ECM_PID == c->pid
149 && (p->PROVID == c->prid || p->PROVID == 0)) // PROVID ==0 some provider no provid in PMT table
152 #ifdef WITH_DEBUG
153 char buf[ECM_FMT_LEN];
154 ecmfmt(buf, ECM_FMT_LEN, c->caid, 0, c->prid, c->chid, c->pid, c->srvid, 0, 0, 0, 0, 0, 0, NULL, NULL);
155 cs_log_dbg(D_DVBAPI, "Demuxer %d found in channel cache: %s", demux_id, buf);
156 #endif
157 return c;
161 return NULL;
164 int32_t dvbapi_edit_channel_cache(int32_t demux_id, int32_t pidindex, uint8_t add)
166 struct s_ecmpid *p = &demux[demux_id].ECMpids[pidindex];
167 struct s_channel_cache *c;
168 LL_ITER it;
169 int32_t count = 0;
171 if(!channel_cache)
172 { channel_cache = ll_create("channel cache"); }
174 it = ll_iter_create(channel_cache);
175 while((c = ll_iter_next(&it)))
177 if(demux[demux_id].program_number == c->srvid
178 && p->CAID == c->caid
179 && p->ECM_PID == c->pid
180 && (p->PROVID == c->prid || p->PROVID == 0))
182 if(add && p->CHID == c->chid)
184 return 0; //already added
186 ll_iter_remove_data(&it);
187 count++;
191 if(add)
193 if(!cs_malloc(&c, sizeof(struct s_channel_cache)))
194 { return count; }
195 c->srvid = demux[demux_id].program_number;
196 c->caid = p->CAID;
197 c->pid = p->ECM_PID;
198 c->prid = p->PROVID;
199 c->chid = p->CHID;
200 ll_append(channel_cache, c);
201 #ifdef WITH_DEBUG
202 char buf[ECM_FMT_LEN];
203 ecmfmt(buf, ECM_FMT_LEN, c->caid, 0, c->prid, c->chid, c->pid, c->srvid, 0, 0, 0, 0, 0, 0, NULL, NULL);
204 cs_log_dbg(D_DVBAPI, "Demuxer %d added to channel cache: %s", demux_id, buf);
205 #endif
206 count++;
209 return count;
212 #endif