source: trunk/module-dvbapi.c@ 8451

Last change on this file since 8451 was 8451, checked in by depp0n, 9 years ago

fixed emm filter in request_mode 1

  • Property svn:eol-style set to LF
File size: 93.4 KB
Line 
1#include "globals.h"
2
3#ifdef HAVE_DVBAPI
4
5#include "module-dvbapi.h"
6#include "module-dvbapi-azbox.h"
7#include "module-dvbapi-mca.h"
8#include "module-dvbapi-coolapi.h"
9#include "module-dvbapi-stapi.h"
10#include "module-stat.h"
11#include "oscam-chk.h"
12#include "oscam-client.h"
13#include "oscam-config.h"
14#include "oscam-ecm.h"
15#include "oscam-emm.h"
16#include "oscam-files.h"
17#include "oscam-net.h"
18#include "oscam-reader.h"
19#include "oscam-string.h"
20#include "oscam-time.h"
21
22// These are declared in module-dvbapi-azbox.c
23extern int32_t openxcas_provid;
24extern uint16_t openxcas_sid, openxcas_caid, openxcas_ecm_pid;
25
26const char *boxdesc[] = { "none", "dreambox", "duckbox", "ufs910", "dbox2", "ipbox", "ipbox-pmt", "dm7000", "qboxhd", "coolstream", "neumo", "pc" };
27
28const struct box_devices devices[BOX_COUNT] = {
29 /* QboxHD (dvb-api-3)*/ { "/tmp/virtual_adapter/", "ca%d", "demux%d", "/tmp/camd.socket", DVBAPI_3 },
30 /* dreambox (dvb-api-3)*/ { "/dev/dvb/adapter%d/", "ca%d", "demux%d", "/tmp/camd.socket", DVBAPI_3 },
31 /* dreambox (dvb-api-1)*/ { "/dev/dvb/card%d/", "ca%d", "demux%d", "/tmp/camd.socket", DVBAPI_1 },
32 /* neumo (dvb-api-1)*/ { "/dev/", "demuxapi", "demuxapi", "/tmp/camd.socket", DVBAPI_1 },
33 /* sh4 (stapi)*/ { "/dev/stapi/", "stpti4_ioctl", "stpti4_ioctl", "/tmp/camd.socket", STAPI },
34 /* coolstream*/ { "/dev/cnxt/", "null", "null", "/tmp/camd.socket", COOLAPI }
35};
36
37int32_t selected_box=-1;
38int32_t selected_api=-1;
39int32_t disable_pmt_files=0;
40int32_t dir_fd=-1, pausecam=0;
41DEMUXTYPE demux[MAX_DEMUX];
42int32_t ca_fd[8];
43LLIST *channel_cache;
44
45struct s_dvbapi_priority *dvbapi_priority=NULL;
46struct s_client *dvbapi_client=NULL;
47
48struct s_emm_filter {
49 int32_t demux_id;
50 uchar filter[32];
51 uint16_t caid;
52 uint32_t provid;
53 uint16_t pid;
54 int32_t count;
55 uint32_t num;
56 time_t time_started;
57} S_EMM_FILTER;
58LLIST *ll_emm_active_filter = NULL;
59LLIST *ll_emm_inactive_filter = NULL;
60LLIST *ll_emm_pending_filter = NULL;
61
62struct s_channel_cache {
63 uint16_t caid;
64 uint32_t prid;
65 uint16_t srvid;
66 uint16_t pid;
67 int8_t chid;
68} CHANNEL_CACHE;
69
70struct s_channel_cache *find_channel_cache(int32_t demux_id, int32_t pidindex, int8_t caid_and_prid_only)
71{
72 struct s_ecmpids *p = &demux[demux_id].ECMpids[pidindex];
73 struct s_channel_cache *c;
74 LL_ITER it;
75
76 if (!channel_cache)
77 channel_cache = ll_create("channel cache");
78
79 it = ll_iter_create(channel_cache);
80 while ((c=ll_iter_next(&it))) {
81
82 if (caid_and_prid_only) {
83 if (p->CAID == c->caid && p->PROVID == c->prid)
84 return c;
85 } else if (demux[demux_id].program_number == c->srvid &&
86 p->CAID == c->caid &&
87 p->ECM_PID == c->pid &&
88 p->PROVID == c->prid &&
89 p->irdeto_curchid == c->chid) {
90
91#ifdef WITH_DEBUG
92 char buf[ECM_FMT_LEN];
93 ecmfmt(c->caid, c->prid, c->chid, c->pid, c->srvid, 0, 0, 0, 0, buf, ECM_FMT_LEN);
94 cs_debug_mask(D_DVBAPI, "found in channel cache: %s", buf);
95#endif
96 return c;
97 }
98 }
99 return NULL;
100}
101
102int32_t edit_channel_cache(int32_t demux_id, int32_t pidindex, uint8_t add)
103{
104 struct s_ecmpids *p = &demux[demux_id].ECMpids[pidindex];
105 struct s_channel_cache *c;
106 LL_ITER it;
107 int32_t count = 0;
108
109 if (!channel_cache)
110 channel_cache = ll_create("channel cache");
111
112 it = ll_iter_create(channel_cache);
113 while ((c=ll_iter_next(&it))) {
114 if (demux[demux_id].program_number == c->srvid &&
115 p->CAID == c->caid &&
116 p->ECM_PID == c->pid &&
117 p->PROVID == c->prid &&
118 p->irdeto_curchid == c->chid) {
119 if (add)
120 return 0; //already added
121 ll_iter_remove_data(&it);
122 count++;
123 }
124 }
125
126 if (add) {
127 if (!cs_malloc(&c, sizeof(struct s_channel_cache)))
128 return count;
129 c->srvid = demux[demux_id].program_number;
130 c->caid = p->CAID;
131 c->pid = p->ECM_PID;
132 c->prid = p->PROVID;
133 c->chid = p->irdeto_curchid;
134 ll_append(channel_cache, c);
135#ifdef WITH_DEBUG
136 char buf[ECM_FMT_LEN];
137 ecmfmt(c->caid, c->prid, c->chid, c->pid, c->srvid, 0, 0, 0, 0, buf, ECM_FMT_LEN);
138 cs_debug_mask(D_DVBAPI, "added to channel cache: %s", buf);
139#endif
140 count++;
141 }
142
143 return count;
144}
145
146int32_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, time_t now)
147{
148 if (!ll_emm_active_filter)
149 ll_emm_active_filter = ll_create("ll_emm_active_filter");
150
151 if (!ll_emm_inactive_filter)
152 ll_emm_inactive_filter = ll_create("ll_emm_inactive_filter");
153
154 if (!ll_emm_pending_filter)
155 ll_emm_pending_filter = ll_create("ll_emm_pending_filter");
156
157 struct s_emm_filter *filter_item;
158 if (!cs_malloc(&filter_item,sizeof(struct s_emm_filter)))
159 return 0;
160
161 filter_item->demux_id = demux_id;
162 memcpy(filter_item->filter, filter, 32);
163 filter_item->caid = caid;
164 filter_item->provid = provid;
165 filter_item->pid = emmpid;
166 filter_item->count = count;
167 filter_item->num = num;
168 filter_item->time_started = now;
169 if (num>0)
170 ll_append(ll_emm_active_filter, filter_item);
171 else if (num<0)
172 ll_append(ll_emm_pending_filter, filter_item);
173 else
174 ll_append(ll_emm_inactive_filter, filter_item);
175 return 1;
176}
177
178int32_t is_emmfilter_in_list_internal(LLIST *ll, uchar *filter, uint16_t emmpid, uint32_t provid)
179{
180 struct s_emm_filter *filter_item;
181 LL_ITER itr;
182 if (ll_count(ll) > 0) {
183 itr = ll_iter_create(ll);
184 while ((filter_item=ll_iter_next(&itr))) {
185 if (!memcmp(filter_item->filter, filter, 32) && filter_item->pid == emmpid && filter_item->provid == provid)
186 return 1;
187 }
188 }
189 return 0;
190}
191
192int32_t is_emmfilter_in_list(uchar *filter, uint16_t emmpid, uint32_t provid)
193{
194 if (!ll_emm_active_filter)
195 ll_emm_active_filter = ll_create("ll_emm_active_filter");
196
197 if (!ll_emm_inactive_filter)
198 ll_emm_inactive_filter = ll_create("ll_emm_inactive_filter");
199
200 if (!ll_emm_pending_filter)
201 ll_emm_pending_filter = ll_create("ll_emm_pending_filter");
202
203 if (is_emmfilter_in_list_internal(ll_emm_active_filter, filter, emmpid,provid))
204 return 1;
205 if (is_emmfilter_in_list_internal(ll_emm_inactive_filter, filter, emmpid,provid))
206 return 1;
207 if (is_emmfilter_in_list_internal(ll_emm_pending_filter, filter, emmpid,provid))
208 return 1;
209
210 return 0;
211}
212
213struct s_emm_filter *get_emmfilter_by_filternum_internal(LLIST *ll, int32_t demux_id, uint32_t num)
214{
215 struct s_emm_filter *filter;
216 LL_ITER itr;
217 if (ll_count(ll) > 0) {
218 itr = ll_iter_create(ll);
219 while ((filter=ll_iter_next(&itr))) {
220 if (filter->demux_id == demux_id && filter->num == num)
221 return filter;
222 }
223 }
224 return NULL;
225}
226
227struct s_emm_filter *get_emmfilter_by_filternum(int32_t demux_id, uint32_t num)
228{
229 if (!ll_emm_active_filter)
230 ll_emm_active_filter = ll_create("ll_emm_active_filter");
231
232 if (!ll_emm_inactive_filter)
233 ll_emm_inactive_filter = ll_create("ll_emm_inactive_filter");
234
235 if (!ll_emm_pending_filter)
236 ll_emm_pending_filter = ll_create("ll_emm_pending_filter");
237
238 struct s_emm_filter *emm_filter = NULL;
239 emm_filter = get_emmfilter_by_filternum_internal(ll_emm_active_filter, demux_id, num);
240 if (emm_filter)
241 return emm_filter;
242 emm_filter = get_emmfilter_by_filternum_internal(ll_emm_inactive_filter, demux_id, num);
243 if (emm_filter)
244 return emm_filter;
245 emm_filter = get_emmfilter_by_filternum_internal(ll_emm_pending_filter, demux_id, num);
246 if (emm_filter)
247 return emm_filter;
248
249 return NULL;
250}
251
252int8_t remove_emmfilter_from_list_internal(LLIST *ll, int32_t demux_id, uint16_t caid, uint32_t provid, uint16_t pid, uint32_t num)
253{
254 struct s_emm_filter *filter;
255 LL_ITER itr;
256 if (ll_count(ll) > 0) {
257 itr = ll_iter_create(ll);
258 while ((filter=ll_iter_next(&itr))) {
259 if (filter->demux_id == demux_id && filter->caid == caid && filter->provid == provid && filter->pid == pid && filter->num == num) {
260 ll_iter_remove_data(&itr);
261 return 1;
262 }
263 }
264 }
265 return 0;
266}
267
268void remove_emmfilter_from_list(int32_t demux_id, uint16_t caid, uint32_t provid, uint16_t pid, uint32_t num)
269{
270 if (ll_emm_active_filter && remove_emmfilter_from_list_internal(ll_emm_active_filter, demux_id, caid, provid, pid, num))
271 return;
272 if (ll_emm_inactive_filter && remove_emmfilter_from_list_internal(ll_emm_inactive_filter, demux_id, caid, provid, pid, num))
273 return;
274 if (ll_emm_pending_filter && remove_emmfilter_from_list_internal(ll_emm_pending_filter, demux_id, caid, provid, pid, num))
275 return;
276}
277
278int32_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) {
279#if defined WITH_AZBOX || defined WITH_MCA
280 openxcas_caid = demux[demux_id].ECMpids[pidindex].CAID;
281 openxcas_ecm_pid = pid;
282
283 return 1;
284#endif
285 int32_t ret=-1,n=-1,i;
286
287 for (i=0; i<MAX_FILTER && demux[demux_id].demux_fd[i].fd>0; i++);
288
289 if (i>=MAX_FILTER) {
290 cs_debug_mask(D_DVBAPI,"no free filter");
291 return -1;
292 }
293 n=i;
294
295 demux[demux_id].demux_fd[n].pidindex = pidindex;
296 demux[demux_id].demux_fd[n].pid = pid;
297 demux[demux_id].demux_fd[n].caid = caid;
298 demux[demux_id].demux_fd[n].provid = provid;
299 demux[demux_id].demux_fd[n].type = type;
300 demux[demux_id].demux_fd[n].count = count;
301
302 switch(api) {
303 case DVBAPI_3:
304 demux[demux_id].demux_fd[n].fd = dvbapi_open_device(0, demux[demux_id].demux_index, demux[demux_id].adapter_index);
305 struct dmx_sct_filter_params sFP2;
306
307 memset(&sFP2,0,sizeof(sFP2));
308
309 sFP2.pid = pid;
310 sFP2.timeout = timeout;
311 sFP2.flags = DMX_IMMEDIATE_START;
312 memcpy(sFP2.filter.filter,filt,16);
313 memcpy(sFP2.filter.mask,mask,16);
314 ret=ioctl(demux[demux_id].demux_fd[n].fd, DMX_SET_FILTER, &sFP2);
315
316 break;
317 case DVBAPI_1:
318 demux[demux_id].demux_fd[n].fd = dvbapi_open_device(0, demux[demux_id].demux_index, demux[demux_id].adapter_index);
319 struct dmxSctFilterParams sFP1;
320
321 memset(&sFP1,0,sizeof(sFP1));
322
323 sFP1.pid = pid;
324 sFP1.timeout = timeout;
325 sFP1.flags = DMX_IMMEDIATE_START;
326 memcpy(sFP1.filter.filter,filt,16);
327 memcpy(sFP1.filter.mask,mask,16);
328 ret=ioctl(demux[demux_id].demux_fd[n].fd, DMX_SET_FILTER1, &sFP1);
329
330 break;
331#ifdef WITH_STAPI
332 case STAPI:
333 demux[demux_id].demux_fd[n].fd = 1;
334 ret=stapi_set_filter(demux_id, pid, filt, mask, n, demux[demux_id].pmt_file);
335
336 break;
337#endif
338#ifdef WITH_COOLAPI
339 case COOLAPI:
340 demux[demux_id].demux_fd[n].fd = coolapi_open_device(demux[demux_id].demux_index, demux_id);
341 if(demux[demux_id].demux_fd[n].fd > 0)
342 ret = coolapi_set_filter(demux[demux_id].demux_fd[n].fd, n, pid, filt, mask, type);
343 break;
344#endif
345 default:
346 break;
347 }
348
349 if (ret < 0)
350 cs_log("ERROR: Could not start demux filter (errno=%d %s)", errno, strerror(errno));
351
352 if (type==TYPE_EMM && add_to_emm_list)
353 add_emmfilter_to_list(demux_id, filt, caid, provid, pid, count, n, time((time_t *) 0));
354
355 return ret;
356}
357
358static int32_t dvbapi_detect_api(void) {
359#ifdef WITH_COOLAPI
360 selected_api=COOLAPI;
361 selected_box = 5;
362 disable_pmt_files = 1;
363 cs_log("Detected Coolstream API");
364 return 1;
365#else
366 int32_t i,devnum=-1, dmx_fd=0, boxnum = sizeof(devices)/sizeof(struct box_devices);
367 char device_path[128], device_path2[128];
368
369 for (i=0;i<boxnum;i++) {
370 snprintf(device_path2, sizeof(device_path2), devices[i].demux_device, 0);
371 snprintf(device_path, sizeof(device_path), devices[i].path, 0);
372
373 strncat(device_path, device_path2, sizeof(device_path)-strlen(device_path)-1);
374
375 if ((dmx_fd = open(device_path, O_RDWR)) > 0) {
376 devnum=i;
377 close(dmx_fd);
378 break;
379 }
380 }
381
382 if (devnum == -1) return 0;
383 selected_box = devnum;
384 if (selected_box > -1)
385 selected_api=devices[selected_box].api;
386
387#ifdef WITH_STAPI
388 if (devnum == 4 && stapi_open() == 0) {
389 cs_log("ERROR: stapi: setting up stapi failed.");
390 return 0;
391 }
392#endif
393 if (cfg.dvbapi_boxtype == BOXTYPE_NEUMO) {
394 selected_api=DVBAPI_1;
395 }
396
397 cs_log("Detected %s Api: %d", device_path, selected_api);
398#endif
399 return 1;
400}
401
402static int32_t dvbapi_read_device(int32_t dmx_fd, unsigned char *buf, int32_t length)
403{
404 int32_t len, rc;
405 struct pollfd pfd[1];
406
407 pfd[0].fd = dmx_fd;
408 pfd[0].events = (POLLIN | POLLPRI);
409
410 rc = poll(pfd, 1, 7000);
411 if (rc<1) {
412 cs_log("ERROR: Read on %d timed out", dmx_fd);
413 return -1;
414 }
415
416 len = read(dmx_fd, buf, length);
417
418 if (len==-1)
419 cs_log("ERROR: Read error on fd %d (errno=%d %s)", dmx_fd, errno, strerror(errno));
420
421 return len;
422}
423
424int32_t dvbapi_open_device(int32_t type, int32_t num, int32_t adapter) {
425 int32_t dmx_fd;
426 int32_t ca_offset=0;
427 char device_path[128], device_path2[128];
428
429 if (type==0) {
430 snprintf(device_path2, sizeof(device_path2), devices[selected_box].demux_device, num);
431 snprintf(device_path, sizeof(device_path), devices[selected_box].path, adapter);
432
433 strncat(device_path, device_path2, sizeof(device_path)-strlen(device_path)-1);
434 } else {
435 if (cfg.dvbapi_boxtype==BOXTYPE_DUCKBOX || cfg.dvbapi_boxtype==BOXTYPE_DBOX2 || cfg.dvbapi_boxtype==BOXTYPE_UFS910)
436 ca_offset=1;
437
438 if (cfg.dvbapi_boxtype==BOXTYPE_QBOXHD)
439 num=0;
440
441 if (cfg.dvbapi_boxtype==BOXTYPE_PC)
442 num=0;
443
444 snprintf(device_path2, sizeof(device_path2), devices[selected_box].ca_device, num+ca_offset);
445 snprintf(device_path, sizeof(device_path), devices[selected_box].path, adapter);
446
447 strncat(device_path, device_path2, sizeof(device_path)-strlen(device_path)-1);
448 }
449
450 if ((dmx_fd = open(device_path, O_RDWR)) < 0) {
451 cs_log("ERROR: Can't open device %s (errno=%d %s)", device_path, errno, strerror(errno));
452 return -1;
453 }
454
455 cs_debug_mask(D_DVBAPI, "DEVICE open (%s) fd %d", device_path, dmx_fd);
456 return dmx_fd;
457}
458
459int32_t dvbapi_open_netdevice(int32_t UNUSED(type), int32_t UNUSED(num), int32_t adapter) {
460 int32_t socket_fd;
461
462 socket_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
463 if (socket_fd == -1) {
464 cs_log("ERROR: Failed create socket (%d %s)", errno, strerror(errno));
465 } else {
466 struct sockaddr_in saddr;
467 fcntl(socket_fd, F_SETFL, O_NONBLOCK);
468 bzero(&saddr, sizeof(saddr));
469 saddr.sin_family = AF_INET;
470 saddr.sin_port = htons(PORT + adapter); // port = PORT + adapter number
471 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
472 int32_t r = connect(socket_fd, (struct sockaddr *) &saddr, sizeof(saddr));
473 if (r<0) {
474 cs_log("ERROR: Failed to connect socket (%d %s), at localhost, port=%d", errno, strerror(errno), PORT + adapter);
475 close(socket_fd);
476 socket_fd = -1;
477 }
478 }
479
480 cs_debug_mask(D_DVBAPI, "NET DEVICE open (port = %d) fd %d", PORT + adapter, socket_fd);
481 return socket_fd;
482}
483
484int32_t dvbapi_stop_filter(int32_t demux_index, int32_t type) {
485 int32_t g;
486
487 for (g=0;g<MAX_FILTER;g++) {
488 if (demux[demux_index].demux_fd[g].type==type) {
489 dvbapi_stop_filternum(demux_index, g);
490 }
491 }
492
493 return 1;
494}
495
496int32_t dvbapi_stop_filternum(int32_t demux_index, int32_t num)
497{
498 int32_t ret=-1;
499 if (demux[demux_index].demux_fd[num].fd>0) {
500#ifdef WITH_COOLAPI
501 ret=coolapi_remove_filter(demux[demux_index].demux_fd[num].fd, num);
502 coolapi_close_device(demux[demux_index].demux_fd[num].fd);
503#else
504#ifdef WITH_STAPI
505 ret=stapi_remove_filter(demux_index, num, demux[demux_index].pmt_file);
506#else
507 ret=ioctl(demux[demux_index].demux_fd[num].fd,DMX_STOP);
508 close(demux[demux_index].demux_fd[num].fd);
509#endif
510#endif
511 if (demux[demux_index].demux_fd[num].type == TYPE_ECM)
512 demux[demux_index].ECMpids[demux[demux_index].demux_fd[num].pidindex].index=0; //filter stopped, reset index
513
514 if (demux[demux_index].demux_fd[num].type == TYPE_EMM && demux[demux_index].demux_fd[num].pid != 0x001)
515 remove_emmfilter_from_list(demux_index, demux[demux_index].demux_fd[num].caid, demux[demux_index].demux_fd[num].provid, demux[demux_index].demux_fd[num].pid, num);
516
517 demux[demux_index].demux_fd[num].fd=0;
518 }
519 return ret;
520}
521
522void 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)
523{
524 uchar filter[32];
525
526 cs_debug_mask(D_DVBAPI, "set filter pid: %04x", pid);
527
528 memset(filter,0,32);
529
530 filter[0]=table;
531 filter[16]=mask;
532
533 dvbapi_set_filter(demux_id, selected_api, pid, caid, 0, filter, filter+16, timeout, pidindex, count, type, 0);
534}
535
536static int32_t dvbapi_find_emmpid(int32_t demux_id, uint8_t type, uint16_t caid, uint32_t provid) {
537 int32_t k;
538 int32_t bck = -1;
539 for (k=0; k<demux[demux_id].EMMpidcount; k++) {
540 if (demux[demux_id].EMMpids[k].CAID == caid
541 && demux[demux_id].EMMpids[k].PROVID == provid
542 && (demux[demux_id].EMMpids[k].type & type))
543 return k;
544 else if (demux[demux_id].EMMpids[k].CAID == caid
545 && (!demux[demux_id].EMMpids[k].PROVID || !provid)
546 && (demux[demux_id].EMMpids[k].type & type) && bck)
547 bck = k;
548 }
549 return bck;
550}
551
552void dvbapi_start_emm_filter(int32_t demux_index) {
553 int32_t j, fcount=0, fcount_added=0;
554 const char *typtext[] = { "UNIQUE", "SHARED", "GLOBAL", "UNKNOWN" };
555
556 if (demux[demux_index].pidindex==-1)
557 return;
558
559 if (!demux[demux_index].EMMpidcount)
560 return;
561
562 if (demux[demux_index].emm_filter)
563 return;
564
565
566 uchar dmx_filter[342]; // 10 filter + 2 byte header
567
568 struct s_reader *rdr = NULL;
569 struct s_client *cl = cur_client();
570 if (!cl || !cl->aureader_list)
571 return;
572
573 LL_ITER itr = ll_iter_create(cl->aureader_list);
574 while ((rdr = ll_iter_next(&itr))) {
575
576 if (!rdr->client || rdr->audisabled !=0 || !rdr->enable || (!is_network_reader(rdr) && rdr->card_status != CARD_INSERTED))
577 continue;
578
579 memset(dmx_filter, 0, sizeof(dmx_filter));
580 dmx_filter[0]=0xFF;
581 dmx_filter[1]=0;
582
583 struct s_cardsystem *cs;
584 if (!rdr->caid)
585 cs = get_cardsystem_by_caid(rdr->csystem.caids[0]); //Bulcrypt
586 else
587 cs = get_cardsystem_by_caid(rdr->caid);
588
589 if (cs)
590 cs->get_emm_filter(rdr, dmx_filter);
591 else {
592 cs_debug_mask(D_DVBAPI, "[EMM Filter] cardsystem for emm filter for %s not found", rdr->label);
593 continue;
594 }
595
596 int32_t filter_count=dmx_filter[1];
597
598 for (j=1;j<=filter_count && j <= 10;j++) {
599 int32_t startpos=2+(34*(j-1));
600
601 if (dmx_filter[startpos+1] != 0x00)
602 continue;
603
604 uchar filter[32];
605 memcpy(filter, dmx_filter+startpos+2, 32);
606 int32_t emmtype=dmx_filter[startpos];
607 //int32_t count=dmx_filter[startpos+1];
608 int32_t l=-1;
609
610 if ( (filter[0] && (((1<<(filter[0] % 0x80)) & rdr->b_nano) && !((1<<(filter[0] % 0x80)) & rdr->s_nano))) )
611 continue;
612
613 if ((rdr->blockemm & emmtype) && !(((1<<(filter[0] % 0x80)) & rdr->s_nano) || (rdr->saveemm & emmtype)))
614 continue;
615
616 if(rdr->caid == 0x100) {
617 uint32_t seca_provid = 0;
618 if (emmtype == EMM_SHARED)
619 seca_provid = ((filter[1] << 8) | filter[2]);
620 l = dvbapi_find_emmpid(demux_index, emmtype, 0x0100, seca_provid);
621 } else {
622 //.. provid 0 is safe since oscam sets filter with e.g. rdr->sa & doesn't add filter twice (is_emmfilter_in_list)
623 if (!rdr->caid) {
624 l = dvbapi_find_emmpid(demux_index, emmtype, rdr->csystem.caids[0], 0); //Bulcrypt
625 if (l<0)
626 l = dvbapi_find_emmpid(demux_index, emmtype, rdr->csystem.caids[1], 0);
627 } else {
628 if (rdr->auprovid) {
629 l = dvbapi_find_emmpid(demux_index, emmtype, rdr->caid, rdr->auprovid);
630 if (l<0)
631 l = dvbapi_find_emmpid(demux_index, emmtype, rdr->caid, 0);
632 } else {
633 l = dvbapi_find_emmpid(demux_index, emmtype, rdr->caid, 0);
634 }
635 }
636 }
637 if (l>-1) {
638 //filter already in list?
639 if (is_emmfilter_in_list(filter, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].PROVID)) {
640 fcount_added++;
641 continue;
642 }
643
644 uint32_t typtext_idx = 0;
645 while (((emmtype >> typtext_idx) & 0x01) == 0 && typtext_idx < sizeof(typtext) / sizeof(const char *)){
646 ++typtext_idx;
647 }
648
649 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);
650 if (fcount>=demux[demux_index].max_emm_filter) {
651 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+1, 0, 0);
652 } else {
653 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+1, TYPE_EMM, 1);
654 }
655 fcount++;
656 demux[demux_index].emm_filter=1;
657 }
658 }
659 }
660 if (fcount)
661 cs_debug_mask(D_DVBAPI,"[EMM Filter] %i matching emm filter found", fcount);
662 if (fcount_added) {
663 demux[demux_index].emm_filter=1;
664 cs_debug_mask(D_DVBAPI,"[EMM Filter] %i matching emm filter skipped because they are already active on same emmpid:provid", fcount_added);
665 }
666}
667
668void dvbapi_add_ecmpid_int(int32_t demux_id, uint16_t caid, uint16_t ecmpid, uint32_t provid) {
669 int32_t n,added=0;
670
671 if (demux[demux_id].ECMpidcount>=ECM_PIDS)
672 return;
673
674 int32_t stream = demux[demux_id].STREAMpidcount-1;
675 for (n=0;n<demux[demux_id].ECMpidcount;n++) {
676 if (stream>-1 && demux[demux_id].ECMpids[n].CAID == caid && demux[demux_id].ECMpids[n].ECM_PID == ecmpid) {
677 if (!demux[demux_id].ECMpids[n].streams) {
678 //we already got this caid/ecmpid as global, no need to add the single stream
679 cs_log("[SKIP STREAM %d] CAID: %04X ECM_PID: %04X PROVID: %06X", n, caid, ecmpid, provid);
680 continue;
681 }
682 added=1;
683 demux[demux_id].ECMpids[n].streams |= (1 << stream);
684 cs_log("[ADD STREAM %d] CAID: %04X ECM_PID: %04X PROVID: %06X", n, caid, ecmpid, provid);
685 }
686 }
687
688 if (added==1)
689 return;
690
691 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].ECM_PID = ecmpid;
692 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CAID = caid;
693 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].PROVID = provid;
694 if (stream>-1)
695 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].streams |= (1 << stream);
696
697 cs_log("[ADD PID %d] CAID: %04X ECM_PID: %04X PROVID: %06X", demux[demux_id].ECMpidcount, caid, ecmpid, provid);
698 demux[demux_id].ECMpidcount++;
699}
700
701void dvbapi_add_ecmpid(int32_t demux_id, uint16_t caid, uint16_t ecmpid, uint32_t provid) {
702 dvbapi_add_ecmpid_int(demux_id, caid, ecmpid, provid);
703 struct s_dvbapi_priority *joinentry;
704 for (joinentry=dvbapi_priority; joinentry != NULL; joinentry=joinentry->next) {
705 if (joinentry->type != 'j') continue;
706 if (joinentry->caid && joinentry->caid != caid) continue;
707 if (joinentry->provid && joinentry->provid != provid) continue;
708 if (joinentry->ecmpid && joinentry->ecmpid != ecmpid) continue;
709 if (joinentry->srvid && joinentry->srvid != demux[demux_id].program_number) continue;
710 cs_debug_mask(D_DVBAPI,"[PMT] Join ECMPID %04X:%06X:%04X to %04X:%06X:%04X", caid, provid, ecmpid, joinentry->mapcaid, joinentry->mapprovid, joinentry->mapecmpid);
711 dvbapi_add_ecmpid_int(demux_id, joinentry->mapcaid, joinentry->mapecmpid, joinentry->mapprovid);
712 }
713}
714
715void dvbapi_add_emmpid(struct s_reader *testrdr, int32_t demux_id, uint16_t caid, uint16_t emmpid, uint32_t provid, uint8_t type) {
716 char typetext[40];
717 cs_strncpy(typetext, ":", sizeof(typetext));
718
719 if (type & 0x01) strcat(typetext, "UNIQUE:");
720 if (type & 0x02) strcat(typetext, "SHARED:");
721 if (type & 0x04) strcat(typetext, "GLOBAL:");
722 if (type & 0xF8) strcat(typetext, "UNKNOWN:");
723
724 if (emm_reader_match(testrdr, caid, provid)){
725 uint16_t i;
726 for (i = 0; i < demux[demux_id].EMMpidcount; i++) {
727 if ((demux[demux_id].EMMpids[i].PID == emmpid)
728 && (demux[demux_id].EMMpids[i].CAID == caid)
729 && (demux[demux_id].EMMpids[i].PROVID == provid)
730 && (demux[demux_id].EMMpids[i].type == type)) {
731 cs_debug_mask(D_DVBAPI,"[SKIP EMMPID] CAID: %04X EMM_PID: %04X PROVID: %06X TYPE %s (same as emmpid #%d)", caid, emmpid, provid,
732 typetext, i);
733 return;
734 }
735 }
736 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].PID = emmpid;
737 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].CAID = caid;
738 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].PROVID = provid;
739 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount++].type = type;
740 cs_debug_mask(D_DVBAPI,"[ADD EMMPID #%d] CAID: %04X EMM_PID: %04X PROVID: %06X TYPE %s", demux[demux_id].EMMpidcount-1, caid, emmpid, provid,
741 typetext);
742 }
743 else {
744 cs_debug_mask(D_DVBAPI,"[IGNORE EMMPID] CAID: %04X EMM_PID: %04X PROVID: %06X TYPE %s (no match)", caid, emmpid, provid, typetext);
745 }
746}
747
748void dvbapi_parse_cat(int32_t demux_id, uchar *buf, int32_t len) {
749 uint16_t i, k;
750 struct s_reader *testrdr = NULL;
751
752 cs_ddump_mask(D_DVBAPI, buf, len, "cat:");
753
754 struct s_client *cl = cur_client();
755 if (!cl || !cl->aureader_list)
756 return;
757
758 LL_ITER itr = ll_iter_create(cl->aureader_list);
759 while ((testrdr = ll_iter_next(&itr))) { // make a list of all readers
760 if (!testrdr->client
761 || (testrdr->audisabled !=0)
762 || (!testrdr->enable)
763 || (!is_network_reader(testrdr) && testrdr->card_status != CARD_INSERTED)){
764 cs_debug_mask(D_DVBAPI,"Reader %s au disabled or not enabled-> skip!", testrdr->label); //only parse au enabled readers that are enabled
765 continue;
766 }
767 cs_debug_mask(D_DVBAPI,"Reader %s au enabled -> parsing cat for emm pids!", testrdr->label);
768
769 for (i = 8; i < (((buf[1] & 0x0F) << 8) | buf[2]) - 1; i += buf[i + 1] + 2) {
770 if (buf[i] != 0x09) continue;
771 if (demux[demux_id].EMMpidcount >= ECM_PIDS) break;
772
773 uint16_t caid=((buf[i + 2] << 8) | buf[i + 3]);
774 uint16_t emm_pid=(((buf[i + 4] & 0x1F) << 8) | buf[i + 5]);
775 uint32_t emm_provider = 0;
776
777
778 switch (caid >> 8) {
779 case 0x01:
780 dvbapi_add_emmpid(testrdr, demux_id, caid, emm_pid, 0, EMM_UNIQUE|EMM_GLOBAL);
781 for (k = i+7; k < i+buf[i+1]+2; k += 4) {
782 emm_provider = (buf[k+2] << 8| buf[k+3]);
783 emm_pid = (buf[k] & 0x0F) << 8 | buf[k+1];
784 dvbapi_add_emmpid(testrdr,demux_id, caid, emm_pid, emm_provider, EMM_SHARED);
785 }
786 break;
787 case 0x05:
788 for (k = i+6; k < i+buf[i+1]+2; k += buf[k+1]+2) {
789 if (buf[k]==0x14) {
790 emm_provider = buf[k+2] << 16 | (buf[k+3] << 8| (buf[k+4] & 0xF0));
791 dvbapi_add_emmpid(testrdr,demux_id, caid, emm_pid, emm_provider, EMM_UNIQUE|EMM_SHARED|EMM_GLOBAL);
792 }
793 }
794 break;
795 case 0x18:
796 emm_provider = (buf[i+1] == 0x07) ? (buf[i+6] << 16 | (buf[i+7] << 8| (buf[i+8]))) : 0;
797 dvbapi_add_emmpid(testrdr,demux_id, caid, emm_pid, emm_provider, EMM_UNIQUE|EMM_SHARED|EMM_GLOBAL);
798 break;
799 default:
800 dvbapi_add_emmpid(testrdr,demux_id, caid, emm_pid, 0, EMM_UNIQUE|EMM_SHARED|EMM_GLOBAL);
801 break;
802 }
803 }
804 }
805
806 return;
807}
808
809static pthread_mutex_t lockindex = PTHREAD_MUTEX_INITIALIZER;
810int32_t dvbapi_get_descindex(void) {
811 pthread_mutex_lock(&lockindex); // to avoid race when readers become responsive!
812 int32_t i,j,idx=1,fail=1;
813 while (fail) {
814 fail=0;
815 for (i=0;i<MAX_DEMUX;i++) {
816 for (j=0;j<demux[i].ECMpidcount;j++) {
817 if (demux[i].ECMpids[j].index==idx) {
818 idx++;
819 fail=1;
820 break;
821 }
822 }
823 }
824 }
825 pthread_mutex_unlock(&lockindex); // and release it!
826 return idx;
827}
828
829void dvbapi_set_pid(int32_t demux_id, int32_t num, int32_t idx) {
830 int32_t i;
831
832 if (demux[demux_id].pidindex == -1) return;
833
834 switch(selected_api) {
835#ifdef WITH_STAPI
836 case STAPI:
837 stapi_set_pid(demux_id, num, idx, demux[demux_id].STREAMpids[num], demux[demux_id].pmt_file);
838 break;
839#endif
840#ifdef WITH_COOLAPI
841 case COOLAPI:
842 break;
843#endif
844 default:
845 for (i=0;i<8;i++) {
846 if (demux[demux_id].ca_mask & (1 << i)) {
847 if (ca_fd[i]<=0) {
848 if (cfg.dvbapi_boxtype == BOXTYPE_PC)
849 ca_fd[i]=dvbapi_open_netdevice(1, i, demux[demux_id].adapter_index);
850 else
851 ca_fd[i]=dvbapi_open_device(1, i, demux[demux_id].adapter_index);
852 }
853 if (ca_fd[i]>0) {
854 ca_pid_t ca_pid2;
855 memset(&ca_pid2,0,sizeof(ca_pid2));
856 ca_pid2.pid = demux[demux_id].STREAMpids[num];
857 ca_pid2.index = idx;
858
859 if (cfg.dvbapi_boxtype == BOXTYPE_PC) {
860 // preparing packet
861 int32_t request = CA_SET_PID;
862 unsigned char packet[sizeof(request) + sizeof(ca_pid2)];
863 memcpy(&packet, &request, sizeof(request));
864 memcpy(&packet[sizeof(request)], &ca_pid2, sizeof(ca_pid2));
865
866 // sending data
867 send(ca_fd[i], &packet, sizeof(packet), 0);
868 } else {
869 // This ioctl fails on dm500 but that is OK.
870 if (ioctl(ca_fd[i], CA_SET_PID, &ca_pid2)==-1)
871 cs_debug_mask(D_TRACE|D_DVBAPI,"ERROR: ioctl(CA_SET_PID) pid=0x%04x index=%d (errno=%d %s)", ca_pid2.pid, ca_pid2.index, errno, strerror(errno));
872 else
873 cs_debug_mask(D_DVBAPI, "CA_SET_PID pid=0x%04x index=%d", ca_pid2.pid, ca_pid2.index);
874 }
875 }
876 }
877 }
878 break;
879 }
880 return;
881}
882
883void dvbapi_stop_descrambling(int32_t demux_id) {
884 int32_t i;
885
886 if (demux[demux_id].program_number==0) return;
887
888 cs_debug_mask(D_DVBAPI, "stop descrambling (demux_id: %d)", demux_id);
889
890 dvbapi_stop_filter(demux_id, TYPE_ECM);
891 dvbapi_stop_filter(demux_id, TYPE_EMM);
892
893 for (i=0;i<demux[demux_id].STREAMpidcount;i++) {
894 dvbapi_set_pid(demux_id, i, -1);
895 }
896 if(cfg.dvbapi_reopenonzap && selected_api != STAPI){
897 for (i=0;i<8;i++) {
898 if (ca_fd[i] && (demux[demux_id].ca_mask & (1 << i))) {
899 int8_t j, found = 0;
900 // Check for other demuxes running on same ca device
901 for(j = 0; j < MAX_DEMUX; ++j){
902 if(j != demux_id && demux[j].pidindex != -1 && (demux[j].ca_mask & (1 << i))) {
903 found = 1;
904 break;
905 }
906 }
907 if(!found){
908 cs_debug_mask(D_DVBAPI, "Closing unused demux device ca%d (fd=%d).", i, ca_fd[i]);
909 close(ca_fd[i]);
910 ca_fd[i] = 0;
911 }
912 }
913 }
914 }
915
916 memset(&demux[demux_id], 0 ,sizeof(DEMUXTYPE));
917 demux[demux_id].pidindex=-1;
918
919 unlink(ECMINFO_FILE);
920
921 return;
922}
923
924void dvbapi_start_descrambling(int32_t demux_id) {
925 int32_t j,k,n;
926 int32_t streamcount=0;
927
928 int32_t last_pidindex = demux[demux_id].pidindex;
929 demux[demux_id].pidindex = demux[demux_id].curindex;
930
931 for (n=0; n<demux[demux_id].ECMpidcount; n++) { // cleanout old indexes of pids that have now status ignore (=no decoding possible!)
932 if (demux[demux_id].ECMpids[n].status == -1) demux[demux_id].ECMpids[n].index = 0; // reset index!
933 }
934 for (j=0; j<demux[demux_id].ECMpidcount; j++) {
935 if (demux[demux_id].curindex == j || (demux[demux_id].ECMpids[demux[demux_id].curindex].CAID == demux[demux_id].ECMpids[j].CAID
936 && demux[demux_id].ECMpids[demux[demux_id].curindex].PROVID == demux[demux_id].ECMpids[j].PROVID
937 && demux[demux_id].ECMpids[j].PROVID > 0
938 && demux[demux_id].ECMpids[demux[demux_id].curindex].ECM_PID == demux[demux_id].ECMpids[j].ECM_PID)) {
939
940 if (demux[demux_id].curindex != j) {
941 if (demux[demux_id].ECMpids[j].status < 0 || !demux[demux_id].ECMpids[demux[demux_id].curindex].streams)
942 continue;
943 demux[demux_id].ECMpids[j].index = 0;
944 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);
945 }
946 if (!demux[demux_id].ECMpids[j].index){ // if no indexer for this pid get one!
947 demux[demux_id].ECMpids[j].index=dvbapi_get_descindex();
948 cs_debug_mask(D_DVBAPI,"DEMUXER: #%d PID: #%d CAID: %04X ECMPID: %04X is using index %d", demux_id, j, demux[demux_id].ECMpids[j].CAID,
949 demux[demux_id].ECMpids[j].ECM_PID, demux[demux_id].ECMpids[j].index-1);
950 }
951 if (!demux[demux_id].ECMpids[j].checked)
952 demux[demux_id].ECMpids[j].checked=1;
953 demux[demux_id].ECMpids[j].irdeto_curchid=demux[demux_id].ECMpids[demux[demux_id].curindex].irdeto_curchid;
954
955 for (k=0;k<demux[demux_id].STREAMpidcount;k++) {
956 if (!demux[demux_id].ECMpids[j].streams || (demux[demux_id].ECMpids[j].streams & (1 << k))) {
957 dvbapi_set_pid(demux_id, k, demux[demux_id].ECMpids[j].index-1);
958 }
959 else
960 dvbapi_set_pid(demux_id, k, -1);
961 }
962
963 streamcount++;
964 }
965 }
966
967 cs_log("Start descrambling PID #%d (CAID: %04X) %d", demux[demux_id].curindex, demux[demux_id].ECMpids[demux[demux_id].curindex].CAID, streamcount);
968
969 if (cfg.dvbapi_au>0 && last_pidindex != demux[demux_id].pidindex && !demux[demux_id].EMMpidcount) {
970 if (last_pidindex != -1) {
971 dvbapi_stop_filter(demux_id, TYPE_EMM);
972 demux[demux_id].emm_filter=0;
973 }
974 dvbapi_start_filter(demux_id, demux[demux_id].pidindex, 0x001, 0x001, 0x01, 0xFF, 0, TYPE_EMM, 0); //CAT
975 }
976}
977
978struct s_dvbapi_priority *dvbapi_check_prio_match_emmpid(int32_t demux_id, uint16_t caid, uint32_t provid, char type) {
979 struct s_dvbapi_priority *p;
980 int32_t i;
981
982 uint16_t ecm_pid=0;
983 for (i=0; i<demux[demux_id].ECMpidcount; i++) {
984 if ((demux[demux_id].ECMpids[i].CAID==caid) && (demux[demux_id].ECMpids[i].PROVID==provid)) {
985 ecm_pid=demux[demux_id].ECMpids[i].ECM_PID;
986 break;
987 }
988 }
989
990 if (!ecm_pid)
991 return NULL;
992
993 for (p=dvbapi_priority, i=0; p != NULL; p=p->next, i++) {
994 if (p->type != type) continue;
995
996 if (p->caid && p->caid != caid) continue;
997 if (p->provid && p->provid != provid) continue;
998 if (p->ecmpid && p->ecmpid != ecm_pid) continue;
999 if (p->srvid && p->srvid != demux[demux_id].program_number) continue;
1000
1001 if (p->type == 'i' && p->chid) continue;
1002
1003 return p;
1004 }
1005 return NULL;
1006
1007}
1008
1009struct s_dvbapi_priority *dvbapi_check_prio_match(int32_t demux_id, int32_t pidindex, char type) {
1010 struct s_dvbapi_priority *p;
1011 struct s_ecmpids *ecmpid = &demux[demux_id].ECMpids[pidindex];
1012 int32_t i;
1013
1014 for (p=dvbapi_priority, i=0; p != NULL; p=p->next, i++) {
1015 if (p->type != type) continue;
1016
1017 if (p->caid && p->caid != ecmpid->CAID) continue;
1018 if (p->provid && p->provid != ecmpid->PROVID) continue;
1019 if (p->ecmpid && p->ecmpid != ecmpid->ECM_PID) continue;
1020 if (p->srvid && p->srvid != demux[demux_id].program_number) continue;
1021
1022 if (p->type == 'i' && p->chid) continue;
1023
1024 return p;
1025 }
1026 return NULL;
1027
1028}
1029
1030void dvbapi_process_emm (int32_t demux_index, int32_t filter_num, unsigned char *buffer, uint32_t len) {
1031 EMM_PACKET epg;
1032
1033 struct s_emm_filter *filter = get_emmfilter_by_filternum(demux_index, filter_num);
1034
1035 if (!filter)
1036 return;
1037
1038 uint32_t provider = filter->provid;
1039 uint16_t caid = filter->caid;
1040
1041 cs_debug_mask(D_DVBAPI, "emm from fd %d", demux[demux_index].demux_fd[filter_num].fd); //emm shown with -d64
1042
1043 struct s_dvbapi_priority *mapentry =dvbapi_check_prio_match_emmpid(filter->demux_id, filter->caid, filter->provid, 'm');
1044 if (mapentry) {
1045 cs_debug_mask(D_DVBAPI, "Mapping EMM from %04X:%06X to %04X:%06X", caid, provider, mapentry->mapcaid, mapentry->mapprovid);
1046 caid = mapentry->mapcaid;
1047 provider = mapentry->mapprovid;
1048 }
1049
1050 memset(&epg, 0, sizeof(epg));
1051
1052 i2b_buf(2, caid, epg.caid);
1053 i2b_buf(4, provider, epg.provid);
1054
1055 epg.emmlen=len;
1056 memcpy(epg.emm, buffer, epg.emmlen);
1057
1058 do_emm(dvbapi_client, &epg);
1059}
1060
1061void dvbapi_read_priority(void) {
1062 FILE *fp;
1063 char token[128], str1[128];
1064 char type;
1065 int32_t i, ret, count=0;
1066
1067 const char *cs_prio="oscam.dvbapi";
1068
1069 fp = fopen(get_config_filename(token, sizeof(token), cs_prio), "r");
1070
1071 if (!fp) {
1072 cs_debug_mask(D_DVBAPI, "ERROR: Can't open priority file %s", token);
1073 return;
1074 }
1075
1076 if (dvbapi_priority) {
1077 cs_debug_mask(D_DVBAPI, "reread priority file %s", cs_prio);
1078 struct s_dvbapi_priority *o, *p;
1079 for (p = dvbapi_priority; p != NULL; p = o) {
1080 o = p->next;
1081 free(p);
1082 }
1083 dvbapi_priority = NULL;
1084 }
1085
1086 while (fgets(token, sizeof(token), fp)) {
1087 // Ignore comments and empty lines
1088 if (token[0]=='#' || token[0]=='/' || token[0]=='\n' || token[0]=='\r' || token[0]=='\0')
1089 continue;
1090 if (strlen(token)>100) continue;
1091
1092 memset(str1, 0, 128);
1093
1094 for (i=0; i<(int)strlen(token) && token[i]==' '; i++);
1095 if (i == (int)strlen(token) - 1) //empty line or all spaces
1096 continue;
1097
1098 for (i=0;i<(int)strlen(token);i++) {
1099 if ((token[i]==':' || token[i]==' ') && token[i+1]==':') { // if "::" or " :"
1100 memmove(token+i+2, token+i+1, strlen(token)-i+1); //insert extra position
1101 token[i+1]='0'; //and fill it with NULL
1102 }
1103 if (token[i]=='#' || token[i]=='/') {
1104 token[i]='\0';
1105 break;
1106 }
1107 }
1108
1109 type = 0;
1110#ifdef WITH_STAPI
1111 uint32_t disablefilter=0;
1112 ret = sscanf(trim(token), "%c: %63s %63s %d", &type, str1, str1+64, &disablefilter);
1113#else
1114 ret = sscanf(trim(token), "%c: %63s %63s", &type, str1, str1+64);
1115#endif
1116 type = tolower(type);
1117
1118 if (ret<1 || (type != 'p' && type != 'i' && type != 'm' && type != 'd' && type != 's' && type != 'l' && type != 'j' && type != 'a' && type != 'x')) {
1119 //fprintf(stderr, "Warning: line containing %s in %s not recognized, ignoring line\n", token, cs_prio);
1120 //fprintf would issue the warning to the command line, which is more consistent with other config warnings
1121 //however it takes OSCam a long time (>4 seconds) to reach this part of the program, so the warnings are reaching tty rather late
1122 //which leads to confusion. So send the warnings to log file instead
1123 cs_debug_mask(D_DVBAPI, "WARN: line containing %s in %s not recognized, ignoring line\n", token, cs_prio);
1124 continue;
1125 }
1126
1127 struct s_dvbapi_priority *entry;
1128 if (!cs_malloc(&entry, sizeof(struct s_dvbapi_priority))) {
1129 fclose(fp);
1130 return;
1131 }
1132
1133 entry->type=type;
1134 entry->next=NULL;
1135
1136 count++;
1137
1138#ifdef WITH_STAPI
1139 if (type=='s') {
1140 strncpy(entry->devname, str1, 29);
1141 strncpy(entry->pmtfile, str1+64, 29);
1142
1143 entry->disablefilter=disablefilter;
1144
1145 cs_debug_mask(D_DVBAPI, "stapi prio: ret=%d | %c: %s %s | disable %d", ret, type, entry->devname, entry->pmtfile, disablefilter);
1146
1147 if (!dvbapi_priority) {
1148 dvbapi_priority=entry;
1149 } else {
1150 struct s_dvbapi_priority *p;
1151 for (p = dvbapi_priority; p->next != NULL; p = p->next);
1152 p->next = entry;
1153 }
1154 continue;
1155 }
1156#endif
1157
1158 char c_srvid[34];
1159 c_srvid[0]='\0';
1160 uint32_t caid=0, provid=0, srvid=0, ecmpid=0, chid=0;
1161 ret = sscanf(str1, "%4x:%6x:%33[^:]:%4x:%4x", &caid, &provid, c_srvid, &ecmpid, &chid);
1162 if (ret < 1) {
1163 cs_debug_mask(D_DVBAPI, "Error in oscam.dvbapi: ret=%d | %c: %04X %06X %s %04X %04X",
1164 ret, type, caid, provid, c_srvid, ecmpid, chid);
1165 continue; // skip this entry!
1166 }
1167 else {
1168 cs_debug_mask(D_DVBAPI, "Parsing rule: ret=%d | %c: %04X %06X %s %04X %04X",
1169 ret, type, caid, provid, c_srvid, ecmpid, chid);
1170 }
1171
1172 entry->caid=caid;
1173 entry->provid=provid;
1174 entry->ecmpid=ecmpid;
1175 entry->chid=chid;
1176
1177 uint32_t delay=0, force=0, mapcaid=0, mapprovid=0, mapecmpid=0;
1178 switch (type) {
1179 case 'd':
1180 sscanf(str1+64, "%4d", &delay);
1181 entry->delay=delay;
1182 break;
1183 case 'l':
1184 entry->delay = dyn_word_atob(str1+64);
1185 if (entry->delay == -1) entry->delay = 0;
1186 break;
1187 case 'p':
1188 sscanf(str1+64, "%1d", &force);
1189 entry->force=force;
1190 break;
1191 case 'm':
1192 sscanf(str1+64, "%4x:%6x", &mapcaid, &mapprovid);
1193 entry->mapcaid=mapcaid;
1194 entry->mapprovid=mapprovid;
1195 break;
1196 case 'a':
1197 case 'j':
1198 sscanf(str1+64, "%4x:%6x:%4x", &mapcaid, &mapprovid, &mapecmpid);
1199 entry->mapcaid=mapcaid;
1200 entry->mapprovid=mapprovid;
1201 entry->mapecmpid=mapecmpid;
1202 break;
1203 }
1204
1205 if (c_srvid[0]=='=') {
1206 struct s_srvid *this;
1207
1208 for (i=0;i<16;i++)
1209 for (this = cfg.srvid[i]; this; this = this->next) {
1210 if (strcmp(this->prov, c_srvid+1)==0) {
1211 struct s_dvbapi_priority *entry2;
1212 if (!cs_malloc(&entry2,sizeof(struct s_dvbapi_priority)))
1213 continue;
1214 memcpy(entry2, entry, sizeof(struct s_dvbapi_priority));
1215
1216 entry2->srvid=this->srvid;
1217
1218 cs_debug_mask(D_DVBAPI, "prio srvid: ret=%d | %c: %04X %06X %04X %04X %04X -> map %04X %06X %04X | prio %d | delay %d",
1219 ret, entry2->type, entry2->caid, entry2->provid, entry2->srvid, entry2->ecmpid, entry2->chid, entry2->mapcaid, entry2->mapprovid, entry2->mapecmpid, entry2->force, entry2->delay);
1220
1221 if (!dvbapi_priority) {
1222 dvbapi_priority=entry2;
1223 } else {
1224 struct s_dvbapi_priority *p;
1225 for (p = dvbapi_priority; p->next != NULL; p = p->next);
1226 p->next = entry2;
1227 }
1228 }
1229 }
1230 free(entry);
1231 continue;
1232 } else {
1233 sscanf(c_srvid, "%4x", &srvid);
1234 entry->srvid=srvid;
1235 }
1236
1237 cs_debug_mask(D_DVBAPI, "prio: ret=%d | %c: %04X %06X %04X %04X %04X -> map %04X %06X %04X | prio %d | delay %d",
1238 ret, entry->type, entry->caid, entry->provid, entry->srvid, entry->ecmpid, entry->chid, entry->mapcaid, entry->mapprovid, entry->mapecmpid, entry->force, entry->delay);
1239
1240 if (!dvbapi_priority) {
1241 dvbapi_priority=entry;
1242 } else {
1243 struct s_dvbapi_priority *p;
1244 for (p = dvbapi_priority; p->next != NULL; p = p->next);
1245 p->next = entry;
1246 }
1247 }
1248
1249 cs_debug_mask(D_DVBAPI, "Read %d entries from %s", count, cs_prio);
1250
1251 fclose(fp);
1252 return;
1253}
1254
1255int32_t chk_valid_btun(ECM_REQUEST *er, uint16_t caidto)
1256{
1257 int32_t i;
1258 struct s_client *cl = cur_client();
1259 TUNTAB *ttab;
1260 ttab = &cl->ttab;
1261
1262 for (i = 0; i<ttab->n; i++) {
1263 if ((er->caid==ttab->bt_caidfrom[i]) &&
1264 ((caidto==ttab->bt_caidto[i])) &&
1265 ((er->srvid==ttab->bt_srvid[i]) || (ttab->bt_srvid[i])==0xFFFF)) {
1266 return 1;
1267 }
1268 }
1269#ifdef WITH_LB
1270 if (cfg.lb_auto_betatunnel && lb_valid_btun(er, caidto))
1271 return 1;
1272
1273#endif
1274 return 0;
1275}
1276
1277void dvbapi_resort_ecmpids(int32_t demux_index) {
1278 int32_t n, cache=0, prio=1, highest_prio=0, matching_done=0;
1279 uint16_t btun_caid=0;
1280
1281 for (n=0; n<demux[demux_index].ECMpidcount; n++) {
1282 demux[demux_index].ECMpids[n].status=0;
1283 demux[demux_index].ECMpids[n].checked=0;
1284 }
1285
1286 demux[demux_index].max_status=0;
1287 demux[demux_index].tries = 0;
1288 demux[demux_index].curindex = 0;
1289 demux[demux_index].pidindex = -1;
1290
1291 if (cfg.dvbapi_requestmode == 1) {
1292 int32_t found=-1;
1293 for (n = 0; n < demux[demux_index].ECMpidcount; n++) {
1294 if (find_channel_cache(demux_index, n, 0)) {
1295 found = n;
1296 break;
1297 }
1298 }
1299 if (found != -1) { //Found in cache
1300 for (n = 0; n < demux[demux_index].ECMpidcount; n++) {
1301 if (n != found)
1302 demux[demux_index].ECMpids[n].status = -1;
1303 else
1304 demux[demux_index].ECMpids[n].status = 1;
1305 }
1306 demux[demux_index].max_emm_filter = MAX_FILTER-1;
1307 demux[demux_index].max_status = 1;
1308 return;
1309 }
1310 } else {
1311 //prioritize CAIDs which already decoded same caid:provid
1312 for (n = 0; n < demux[demux_index].ECMpidcount; n++) {
1313 if (find_channel_cache(demux_index, n, 1)) {
1314 cache=1; //found cache entry
1315 demux[demux_index].ECMpids[n].status = prio;
1316 cs_debug_mask(D_DVBAPI,"[PRIORITIZE PID %d] %04X:%06X:%04X (found caid/provid in cache - weight: %d)", n,
1317 demux[demux_index].ECMpids[n].CAID,demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID,
1318 demux[demux_index].ECMpids[n].status);
1319 }
1320 }
1321
1322 //prioritize CAIDs which already decoded same caid:provid:srvid
1323 for (n = 0; n < demux[demux_index].ECMpidcount; n++) {
1324 if (find_channel_cache(demux_index, n, 0)) {
1325 cache=2; //found cache entry with higher priority
1326 demux[demux_index].ECMpids[n].status = prio*2;
1327 cs_debug_mask(D_DVBAPI,"[PRIORITIZE PID %d] %04X:%06X:%04X (found caid/provid/srvid in cache - weight: %d)", n,
1328 demux[demux_index].ECMpids[n].CAID,demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID,
1329 demux[demux_index].ECMpids[n].status);
1330 }
1331 }
1332 }
1333
1334 //prioritize & ignore according to oscam.dvbapi and cfg.preferlocalcards
1335 if (dvbapi_priority) {
1336 struct s_reader *rdr;
1337 ECM_REQUEST *er;
1338 if (!cs_malloc(&er, sizeof(ECM_REQUEST)))
1339 return;
1340
1341 int32_t add_prio=0; // make sure that p: values overrule cache
1342 if (cache==1)
1343 add_prio = prio;
1344 else if (cache==2)
1345 add_prio = prio*2;
1346
1347 int32_t p_order = demux[demux_index].ECMpidcount; // reverse order! makes sure that user defined p: values are in the right order
1348
1349 highest_prio = (prio * demux[demux_index].ECMpidcount) + p_order;
1350
1351 struct s_dvbapi_priority *p;
1352 for (p = dvbapi_priority; p != NULL; p = p->next) {
1353 if (p->type != 'p' && p->type != 'i')
1354 continue;
1355 for (n = 0; n < demux[demux_index].ECMpidcount; n++) {
1356 if (!cache && demux[demux_index].ECMpids[n].status != 0)
1357 continue;
1358 else if (cache==1 && (demux[demux_index].ECMpids[n].status < 0 || demux[demux_index].ECMpids[n].status > prio))
1359 continue;
1360 else if (cache==2 && (demux[demux_index].ECMpids[n].status < 0 || demux[demux_index].ECMpids[n].status > prio*2))
1361 continue;
1362
1363 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
1364 er->prid = demux[demux_index].ECMpids[n].PROVID;
1365 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
1366 er->srvid = demux[demux_index].program_number;
1367 er->client = cur_client();
1368
1369 btun_caid = get_betatunnel_caid_to(er->caid);
1370 if (p->type == 'p' && btun_caid) {
1371 if (chk_valid_btun(er, btun_caid))
1372 er->caid = btun_caid;
1373 }
1374
1375 if (p->caid && p->caid != er->caid)
1376 continue;
1377 if (p->provid && p->provid != er->prid)
1378 continue;
1379 if (p->ecmpid && p->ecmpid != er->pid)
1380 continue;
1381 if (p->srvid && p->srvid != er->srvid)
1382 continue;
1383
1384 if (p->type == 'i') { // check if ignored by dvbapi
1385 if (p->chid)
1386 continue;
1387 demux[demux_index].ECMpids[n].status = -1;
1388 cs_debug_mask(D_DVBAPI,"[IGNORE PID %d] %04X:%06X:%04X (file)", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID,demux[demux_index].ECMpids[n].ECM_PID);
1389 continue;
1390 }
1391
1392 if (p->type == 'p') {
1393 if (demux[demux_index].ECMpids[n].status == -1) //skip ignores
1394 continue;
1395
1396 matching_done = 1;
1397
1398 for (rdr=first_active_reader; rdr ; rdr=rdr->next) {
1399 if (cfg.preferlocalcards
1400 && !is_network_reader(rdr)
1401 && rdr->card_status == CARD_INSERTED) { // cfg.preferlocalcards = 1 local reader
1402 if (matching_reader(er, rdr, 0)) {
1403 if (cache==2 && demux[demux_index].ECMpids[n].status==1)
1404 demux[demux_index].ECMpids[n].status++;
1405 else if (cache && !demux[demux_index].ECMpids[n].status)
1406 demux[demux_index].ECMpids[n].status += add_prio;
1407 demux[demux_index].ECMpids[n].status += (prio * demux[demux_index].ECMpidcount) + (p_order--); //priority*ECMpidcount should overrule network reader
1408 cs_debug_mask(D_DVBAPI,"[PRIORITIZE PID %d] %04X:%06X:%04X (localrdr: %s weight: %d)", n, demux[demux_index].ECMpids[n].CAID,
1409 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, rdr->label, demux[demux_index].ECMpids[n].status);
1410 break;
1411 } else {
1412 if (!rdr->next) // no match so ignore it!
1413 demux[demux_index].ECMpids[n].status = -1;
1414 }
1415 } else { // cfg.preferlocalcards = 0 or cfg.preferlocalcards = 1 and no local reader
1416 if (matching_reader(er, rdr, 0)) {
1417 if (cache==2 && demux[demux_index].ECMpids[n].status==1)
1418 demux[demux_index].ECMpids[n].status++;
1419 else if (cache && !demux[demux_index].ECMpids[n].status)
1420 demux[demux_index].ECMpids[n].status += add_prio;
1421 demux[demux_index].ECMpids[n].status += prio + (p_order--);
1422 cs_debug_mask(D_DVBAPI,"[PRIORITIZE PID %d] %04X:%06X:%04X (rdr: %s weight: %d)", n, demux[demux_index].ECMpids[n].CAID,
1423 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, rdr->label, demux[demux_index].ECMpids[n].status);
1424 break;
1425 } else {
1426 if (!rdr->next) // no match so ignore it!
1427 demux[demux_index].ECMpids[n].status = -1;
1428 }
1429 }
1430 }
1431 if (demux[demux_index].ECMpids[n].status == -1)
1432 cs_debug_mask(D_DVBAPI,"[IGNORE PID %d] %04X:%06X:%04X (no matching reader)", n, demux[demux_index].ECMpids[n].CAID,
1433 demux[demux_index].ECMpids[n].PROVID,demux[demux_index].ECMpids[n].ECM_PID);
1434 }
1435 }
1436 }
1437 free(er);
1438 }
1439
1440 if (!dvbapi_priority || !matching_done) { //works if there is no oscam.dvbapi or if there is oscam.dvbapi but not p rules in it
1441 struct s_reader *rdr;
1442 ECM_REQUEST *er;
1443 if (!cs_malloc(&er, sizeof(ECM_REQUEST)))
1444 return;
1445
1446 highest_prio = prio*2;
1447
1448 for (n=0; n<demux[demux_index].ECMpidcount; n++) {
1449 if (demux[demux_index].ECMpids[n].status == -1) //skip ignores
1450 continue;
1451
1452 matching_done=1;
1453
1454 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
1455 er->prid = demux[demux_index].ECMpids[n].PROVID;
1456 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
1457 er->srvid = demux[demux_index].program_number;
1458 er->client = cur_client();
1459
1460 btun_caid = get_betatunnel_caid_to(er->caid);
1461 if (btun_caid) {
1462 if (chk_valid_btun(er, btun_caid))
1463 er->caid = btun_caid;
1464 }
1465
1466 for (rdr=first_active_reader; rdr ; rdr=rdr->next) {
1467 if (cfg.preferlocalcards
1468 && !is_network_reader(rdr)
1469 && rdr->card_status==CARD_INSERTED) { // cfg.preferlocalcards = 1 local reader
1470 if (matching_reader(er, rdr, 0)) {
1471 demux[demux_index].ECMpids[n].status += prio*2;
1472 cs_debug_mask(D_DVBAPI,"[PRIORITIZE PID %d] %04X:%06X:%04X (localrdr: %s weight: %d)", n, demux[demux_index].ECMpids[n].CAID,
1473 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, rdr->label, demux[demux_index].ECMpids[n].status);
1474 break;
1475 } else {
1476 if (!rdr->next) // no match so ignore it!
1477 demux[demux_index].ECMpids[n].status = -1;
1478 }
1479 } else { // cfg.preferlocalcards = 0 or cfg.preferlocalcards = 1 and no local reader
1480 if (matching_reader(er, rdr, 0)) {
1481 demux[demux_index].ECMpids[n].status += prio;
1482 cs_debug_mask(D_DVBAPI,"[PRIORITIZE PID %d] %04X:%06X:%04X (rdr: %s weight: %d)", n, demux[demux_index].ECMpids[n].CAID,
1483 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, rdr->label, demux[demux_index].ECMpids[n].status);
1484 break;
1485 } else {
1486 if (!rdr->next) // no match so ignore it!
1487 demux[demux_index].ECMpids[n].status = -1;
1488 }
1489 }
1490 }
1491 if (demux[demux_index].ECMpids[n].status == -1)
1492 cs_debug_mask(D_DVBAPI,"[IGNORE PID %d] %04X:%06X:%04X (no matching reader)", n, demux[demux_index].ECMpids[n].CAID,
1493 demux[demux_index].ECMpids[n].PROVID,demux[demux_index].ECMpids[n].ECM_PID);
1494 }
1495 free(er);
1496 }
1497
1498 if (cache==1)
1499 highest_prio += prio;
1500 else if (cache==2)
1501 highest_prio += prio*2;
1502
1503 highest_prio++;
1504
1505 for (n=demux[demux_index].ECMpidcount; n>-1; n--) { //maintain pid prio order of the pmt.
1506 int32_t nr;
1507 SIDTAB *sidtab;
1508 ECM_REQUEST er;
1509 er.caid = demux[demux_index].ECMpids[n].CAID;
1510 er.prid = demux[demux_index].ECMpids[n].PROVID;
1511 er.srvid = demux[demux_index].program_number;
1512
1513 for (nr=0, sidtab=cfg.sidtab; sidtab; sidtab=sidtab->next, nr++) {
1514 if (sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid) {
1515 if ((cfg.dvbapi_sidtabs.no&((SIDTABBITS)1<<nr)) && (chk_srvid_match(&er, sidtab))) {
1516 demux[demux_index].ECMpids[n].status = -1; //ignore
1517 cs_debug_mask(D_DVBAPI,"[IGNORE PID %d] %04X:%06X:%04X (service %s) pos %d", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, sidtab->label, nr);
1518 }
1519 if ((cfg.dvbapi_sidtabs.ok&((SIDTABBITS)1<<nr)) && (chk_srvid_match(&er, sidtab))) {
1520 demux[demux_index].ECMpids[n].status = highest_prio++; //priority
1521 cs_debug_mask(D_DVBAPI,"[PRIORITIZE PID %d] %04X:%06X:%04X (service: %s position: %d)", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, sidtab->label, demux[demux_index].ECMpids[n].status);
1522 }
1523 }
1524 }
1525 }
1526
1527#ifdef WITH_COOLAPI
1528 // driver sometimes reports error if too many emm filter
1529 // but adding more ecm filter is no problem
1530 // ... so ifdef here instead of limiting MAX_FILTER
1531 demux[demux_index].max_emm_filter = 14;
1532#else
1533 if (cfg.dvbapi_requestmode == 1) {
1534 uint16_t ecm_filter_needed=0;
1535 for (n=0; n<demux[demux_index].ECMpidcount; n++) {
1536 if (demux[demux_index].ECMpids[n].status > -1)
1537 ecm_filter_needed++;
1538 }
1539 if (MAX_FILTER-ecm_filter_needed<=0)
1540 demux[demux_index].max_emm_filter = 0;
1541 else
1542 demux[demux_index].max_emm_filter = MAX_FILTER-ecm_filter_needed;
1543 } else {
1544 demux[demux_index].max_emm_filter = MAX_FILTER-1;
1545 }
1546#endif
1547
1548 demux[demux_index].max_status = highest_prio;
1549 return;
1550}
1551
1552
1553void dvbapi_parse_descriptor(int32_t demux_id, uint32_t info_length, unsigned char *buffer) {
1554 //int32_t ca_pmt_cmd_id = buffer[i + 5];
1555 uint32_t descriptor_length=0;
1556 uint32_t j,u;
1557
1558 if (info_length<1)
1559 return;
1560
1561 if (buffer[0]==0x01) {
1562 buffer=buffer+1;
1563 info_length--;
1564 }
1565
1566 for (j = 0; j < info_length; j += descriptor_length + 2) {
1567 descriptor_length = buffer[j+1];
1568 int32_t descriptor_ca_system_id = (buffer[j+2] << 8) | buffer[j+3];
1569 int32_t descriptor_ca_pid = ((buffer[j+4] & 0x1F) << 8) | buffer[j+5];
1570 int32_t descriptor_ca_provider = 0;
1571
1572 if (demux[demux_id].ECMpidcount>=ECM_PIDS)
1573 break;
1574
1575 cs_debug_mask(D_DVBAPI, "[pmt] type: %02x length: %d", buffer[j], descriptor_length);
1576
1577 if (buffer[j] != 0x09) continue;
1578
1579 if (descriptor_ca_system_id >> 8 == 0x01) {
1580 for (u=2; u<descriptor_length; u+=15) {
1581 descriptor_ca_pid = ((buffer[j+2+u] & 0x1F) << 8) | buffer[j+2+u+1];
1582 descriptor_ca_provider = (buffer[j+2+u+2] << 8) | buffer[j+2+u+3];
1583 dvbapi_add_ecmpid(demux_id, descriptor_ca_system_id, descriptor_ca_pid, descriptor_ca_provider);
1584 }
1585 } else {
1586 if (descriptor_ca_system_id >> 8 == 0x05 && descriptor_length == 0x0F && buffer[j+12] == 0x14)
1587 descriptor_ca_provider = buffer[j+14] << 16 | (buffer[j+15] << 8| (buffer[j+16] & 0xF0));
1588
1589 if (descriptor_ca_system_id >> 8 == 0x18 && descriptor_length == 0x07)
1590 descriptor_ca_provider = (buffer[j+7] << 8| (buffer[j+8]));
1591
1592 if (descriptor_ca_system_id >> 8 == 0x4A && descriptor_length == 0x05)
1593 descriptor_ca_provider = buffer[j+6];
1594
1595 dvbapi_add_ecmpid(demux_id, descriptor_ca_system_id, descriptor_ca_pid, descriptor_ca_provider);
1596 }
1597 }
1598
1599 //Apply mapping:
1600 if (dvbapi_priority) {
1601 struct s_dvbapi_priority *mapentry;
1602 for (j = 0; (int32_t)j < demux[demux_id].ECMpidcount; j++) {
1603 mapentry = dvbapi_check_prio_match(demux_id, j, 'm');
1604 if (mapentry) {
1605 cs_debug_mask(D_DVBAPI,"mapping ECM from %04X:%06X to %04X:%06X",
1606 demux[demux_id].ECMpids[j].CAID, demux[demux_id].ECMpids[j].PROVID,
1607 mapentry->mapcaid, mapentry->mapprovid);
1608 demux[demux_id].ECMpids[j].CAID = mapentry->mapcaid;
1609 demux[demux_id].ECMpids[j].PROVID = mapentry->mapprovid;
1610 }
1611 }
1612 }
1613}
1614
1615void request_cw(struct s_client *client, ECM_REQUEST *er)
1616{
1617#ifdef WITH_DEBUG
1618 char buf[ECM_FMT_LEN];
1619 format_ecm(er, buf, ECM_FMT_LEN);
1620 cs_debug_mask(D_DVBAPI, "dvbapi request cw for %s", buf);
1621#endif
1622 get_cw(client, er);
1623}
1624
1625void dvbapi_try_next_caid(int32_t demux_id) {
1626 int32_t num=-1, n, j;
1627 if (cfg.dvbapi_decodeforever && demux[demux_id].tries > 2){
1628 dvbapi_resort_ecmpids(demux_id);
1629 cs_sleepms(150);
1630 dvbapi_start_descrambling(demux_id);
1631 return;
1632 }
1633
1634 if (demux[demux_id].tries > 2) {
1635 cs_log("ERROR: Can't decode channel");
1636 dvbapi_stop_filter(demux_id, TYPE_ECM);
1637 return;
1638 }
1639
1640 //values for first run (status > 0)
1641 int32_t start=1;
1642 int32_t end=demux[demux_id].max_status;
1643
1644 while (num==-1) {
1645 for (j = end; j >= start && num == -1; j--) { //largest status first!
1646 for (n=0; n<demux[demux_id].ECMpidcount; n++) {
1647 if (demux[demux_id].ECMpids[n].checked == 0 && demux[demux_id].ECMpids[n].status == j) {
1648 num=n;
1649 break;
1650 }
1651 }
1652 }
1653 if (start==0 || num>-1) break;
1654 //values for second run (status==0)
1655 start=0;
1656 end=0;
1657 }
1658
1659 if (num == -1) {
1660 if (cfg.dvbapi_requestmode == 1)
1661 return;
1662
1663 demux[demux_id].tries++;
1664 cs_debug_mask(D_DVBAPI,"try pids again #%d", demux[demux_id].tries);
1665 for (n=0; n<demux[demux_id].ECMpidcount; n++) {
1666 demux[demux_id].ECMpids[n].checked=0;
1667 demux[demux_id].ECMpids[n].irdeto_curchid=0;
1668 demux[demux_id].ECMpids[n].irdeto_chids=0;
1669 demux[demux_id].ECMpids[n].irdeto_cycle=0;
1670 demux[demux_id].ECMpids[n].table=0;
1671 }
1672 dvbapi_try_next_caid(demux_id);
1673 return;
1674 }
1675
1676 if (cfg.dvbapi_requestmode != 1){
1677 dvbapi_stop_filter(demux_id, TYPE_ECM);
1678 }
1679
1680 cs_debug_mask(D_DVBAPI,"[TRY PID %d] CAID: %04X PROVID: %06X CA_PID: %04X", num, demux[demux_id].ECMpids[num].CAID, demux[demux_id].ECMpids[num].PROVID, demux[demux_id].ECMpids[num].ECM_PID);
1681#if defined WITH_AZBOX || defined WITH_MCA
1682 openxcas_provid = demux[demux_id].ECMpids[num].PROVID;
1683 openxcas_caid = demux[demux_id].ECMpids[num].CAID;
1684 openxcas_ecm_pid = demux[demux_id].ECMpids[num].ECM_PID;
1685#endif
1686 demux[demux_id].curindex=num;
1687
1688 demux[demux_id].ECMpids[num].checked=1;
1689
1690 //BISS or FAKE CAID
1691 //ecm stream pid is fake, so send out one fake ecm request
1692 if (demux[demux_id].ECMpids[num].CAID == 0xFFFF || (demux[demux_id].ECMpids[num].CAID >> 8) == 0x26) {
1693 ECM_REQUEST *er;
1694 if (!(er=get_ecmtask()))
1695 return;
1696
1697 er->srvid = demux[demux_id].program_number;
1698 er->caid = demux[demux_id].ECMpids[num].CAID;
1699 er->pid = demux[demux_id].ECMpids[num].ECM_PID;
1700 er->prid = demux[demux_id].ECMpids[num].PROVID;
1701
1702 er->ecmlen=5;
1703 er->ecm[1] = 0x00;
1704 er->ecm[2] = 0x02;
1705 i2b_buf(2, er->srvid, er->ecm+3);
1706
1707 for (j=0, n=5; j<demux[demux_id].STREAMpidcount; j++, n+=2) {
1708 i2b_buf(2, demux[demux_id].STREAMpids[j], er->ecm+n);
1709 er->ecm[2] += 2;
1710 er->ecmlen += 2;
1711 }
1712
1713 request_cw(dvbapi_client, er);
1714
1715 if (cfg.dvbapi_requestmode == 1)
1716 dvbapi_try_next_caid(demux_id);
1717
1718 return;
1719 }
1720
1721 if (cfg.dvbapi_requestmode == 1) {
1722 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);
1723 dvbapi_try_next_caid(demux_id);
1724 } else {
1725 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);
1726 }
1727}
1728
1729static void getDemuxOptions(int32_t demux_id, unsigned char *buffer, uint16_t *ca_mask, uint16_t *demux_index, uint16_t *adapter_index){
1730#ifdef WITH_MCA
1731 *ca_mask=0x03, *demux_index=0x01, *adapter_index=0x00;
1732#else
1733 *ca_mask=0x01, *demux_index=0x00, *adapter_index=0x00;
1734#endif
1735
1736 if (buffer[17]==0x82 && buffer[18]==0x02) {
1737 //enigma2
1738 *ca_mask = buffer[19];
1739 *demux_index = buffer[20];
1740 }
1741
1742 if (cfg.dvbapi_boxtype == BOXTYPE_IPBOX_PMT) {
1743 *ca_mask = demux_id + 1;
1744 *demux_index = demux_id;
1745 }
1746
1747 if (cfg.dvbapi_boxtype == BOXTYPE_QBOXHD && buffer[17]==0x82 && buffer[18]==0x03) {
1748 //ca_mask = buffer[19]; // with STONE 1.0.4 always 0x01
1749 *demux_index = buffer[20]; // with STONE 1.0.4 always 0x00
1750 *adapter_index = buffer[21]; // with STONE 1.0.4 adapter index can be 0,1,2
1751 *ca_mask = (1 << *adapter_index); // use adapter_index as ca_mask (used as index for ca_fd[] array)
1752 }
1753
1754 if (cfg.dvbapi_boxtype == BOXTYPE_PC && buffer[7]==0x82 && buffer[8]==0x02) {
1755 *demux_index = buffer[9]; // it is always 0 but you never know
1756 *adapter_index = buffer[10]; // adapter index can be 0,1,2
1757 *ca_mask = (1 << *adapter_index); // use adapter_index as ca_mask (used as index for ca_fd[] array)
1758 }
1759}
1760
1761int32_t dvbapi_parse_capmt(unsigned char *buffer, uint32_t length, int32_t connfd, char *pmtfile) {
1762 uint32_t i;
1763 int32_t demux_id=-1;
1764 uint16_t ca_mask, demux_index, adapter_index;
1765
1766#ifdef WITH_COOLAPI
1767 int32_t ca_pmt_list_management = 0x03;
1768#else
1769 int32_t ca_pmt_list_management = buffer[0];
1770#endif
1771 uint32_t program_number = (buffer[1] << 8) | buffer[2];
1772 uint32_t program_info_length = ((buffer[4] & 0x0F) << 8) | buffer[5];
1773
1774 cs_ddump_mask(D_DVBAPI, buffer, length, "capmt:");
1775
1776 for (i = 0; i < MAX_DEMUX; i++) {
1777#ifdef WITH_COOLAPI
1778 if (connfd>0 && demux[i].program_number==program_number) {
1779#else
1780 if (connfd>0 && demux[i].socket_fd == connfd) {
1781#endif
1782 //PMT Update
1783 if (ca_pmt_list_management == 0x05) {
1784 demux_id = i;
1785 demux[demux_id].curindex = demux[demux_id].pidindex;
1786 demux[demux_id].STREAMpidcount=0;
1787 demux[demux_id].ECMpidcount=0;
1788 demux[demux_id].EMMpidcount=0;
1789 }
1790 if (ca_pmt_list_management == 0x03 || ca_pmt_list_management == 0x01)
1791 dvbapi_stop_descrambling(i);
1792 if (ca_pmt_list_management == 0x02)
1793 demux_id=i;
1794 }
1795 }
1796
1797 if (demux_id==-1)
1798 for (demux_id=0; demux_id<MAX_DEMUX && demux[demux_id].program_number>0; demux_id++);
1799
1800 if (demux_id>=MAX_DEMUX) {
1801 cs_log("ERROR: No free id (MAX_DEMUX)");
1802 return -1;
1803 }
1804
1805 getDemuxOptions(demux_id, buffer, &ca_mask, &demux_index, &adapter_index);
1806
1807 if (buffer[7]==0x81 && buffer[8]==0x08) {
1808 // parse private descriptor as used by enigma (4 bytes namespace, 2 tsid, 2 onid)
1809 demux[demux_id].enigma_namespace=(buffer[9] << 24 | buffer[10] << 16 | buffer[11] << 8 | buffer[12]);
1810 demux[demux_id].tsid=(buffer[13] << 8 | buffer[14]);
1811 demux[demux_id].onid=(buffer[15] << 8 | buffer[16]);
1812 } else {
1813 demux[demux_id].enigma_namespace=0;
1814 demux[demux_id].tsid=0;
1815 demux[demux_id].onid=0;
1816 }
1817
1818
1819 demux[demux_id].program_number=program_number;
1820 demux[demux_id].demux_index=demux_index;
1821 demux[demux_id].adapter_index=adapter_index;
1822 demux[demux_id].ca_mask=ca_mask;
1823 demux[demux_id].socket_fd=connfd;
1824 demux[demux_id].rdr=NULL;
1825 demux[demux_id].pidindex=-1;
1826
1827 cs_debug_mask(D_DVBAPI, "id: %2d demux_index: %2d ca_mask: %02x program_info_length: %3d ca_pmt_list_management %02x",
1828 demux_id, demux[demux_id].demux_index, demux[demux_id].ca_mask, program_info_length, ca_pmt_list_management);
1829
1830 if (pmtfile)
1831 cs_strncpy(demux[demux_id].pmt_file, pmtfile, sizeof(demux[demux_id].pmt_file));
1832
1833 if (program_info_length > 1 && program_info_length < length)
1834 dvbapi_parse_descriptor(demux_id, program_info_length-1, buffer+7);
1835
1836 uint32_t es_info_length=0;
1837 struct s_dvbapi_priority *addentry;
1838 for (i = program_info_length + 6; i < length; i += es_info_length + 5) {
1839 int32_t stream_type = buffer[i];
1840 uint16_t elementary_pid = ((buffer[i + 1] & 0x1F) << 8) | buffer[i + 2];
1841 es_info_length = ((buffer[i + 3] & 0x0F) << 8) | buffer[i + 4];
1842
1843 cs_debug_mask(D_DVBAPI, "[pmt] stream_type: %02x pid: %04x length: %d", stream_type, elementary_pid, es_info_length);
1844
1845 if (demux[demux_id].STREAMpidcount >= ECM_PIDS)
1846 break;
1847
1848 demux[demux_id].STREAMpids[demux[demux_id].STREAMpidcount++]=elementary_pid;
1849
1850 if (es_info_length != 0 && es_info_length < length) {
1851 dvbapi_parse_descriptor(demux_id, es_info_length, buffer+i+5);
1852 } else {
1853 for (addentry=dvbapi_priority; addentry != NULL; addentry=addentry->next) {
1854 if (addentry->type != 'a') continue;
1855 if (addentry->ecmpid && addentry->ecmpid != elementary_pid) continue;
1856 if (addentry->srvid != demux[demux_id].program_number) continue;
1857 cs_debug_mask(D_DVBAPI,"[pmt] Add Fake FFFF:%06x:%04x for unencrypted stream on srvid %04X", addentry->mapprovid, addentry->mapecmpid, demux[demux_id].program_number);
1858 dvbapi_add_ecmpid(demux_id, 0xFFFF, addentry->mapecmpid, addentry->mapprovid);
1859 break;
1860 }
1861 }
1862 }
1863 cs_log("Found %d ECMpids and %d STREAMpids in PMT", demux[demux_id].ECMpidcount, demux[demux_id].STREAMpidcount);
1864
1865 char channame[32];
1866 get_servicename(dvbapi_client, demux[demux_id].program_number, demux[demux_id].ECMpidcount>0 ? demux[demux_id].ECMpids[0].CAID : 0, channame);
1867 cs_log("New program number: %04X (%s) [pmt_list_management %d]", program_number, channame, ca_pmt_list_management);
1868
1869 struct s_dvbapi_priority *xtraentry;
1870 int32_t j, k, l, m, xtra_demux_id;
1871 for (xtraentry=dvbapi_priority; xtraentry != NULL; xtraentry=xtraentry->next) {
1872 if (xtraentry->type != 'x') continue;
1873 for(j = 0; j <= demux[demux_id].ECMpidcount; ++j){
1874 if (xtraentry->caid && xtraentry->caid != demux[demux_id].ECMpids[j].CAID) continue;
1875 if (xtraentry->provid && xtraentry->provid != demux[demux_id].ECMpids[j].PROVID) continue;
1876 if (xtraentry->ecmpid && xtraentry->ecmpid != demux[demux_id].ECMpids[j].ECM_PID) continue;
1877 if (xtraentry->srvid && xtraentry->srvid != demux[demux_id].program_number) continue;
1878 cs_log("[pmt] Mapping %04X:%06X:%04X:%04X to xtra demuxer/ca-devices", xtraentry->caid, xtraentry->provid, xtraentry->ecmpid, xtraentry->srvid);
1879 for (xtra_demux_id=0; xtra_demux_id<MAX_DEMUX && demux[xtra_demux_id].program_number>0; xtra_demux_id++);
1880 if (xtra_demux_id>=MAX_DEMUX) {
1881 cs_log("Found no free demux device for xtra streams.");
1882 continue;
1883 }
1884
1885 getDemuxOptions(xtra_demux_id, buffer, &ca_mask, &demux_index, &adapter_index);
1886
1887 // copy to new demuxer
1888 demux[xtra_demux_id].ECMpids[0] = demux[demux_id].ECMpids[j];
1889 demux[xtra_demux_id].ECMpidcount = 1;
1890 demux[xtra_demux_id].STREAMpidcount = 0;
1891 demux[xtra_demux_id].program_number=demux[demux_id].program_number;
1892 demux[xtra_demux_id].demux_index=demux_index;
1893 demux[xtra_demux_id].adapter_index=adapter_index;
1894 demux[xtra_demux_id].ca_mask=ca_mask;
1895 demux[xtra_demux_id].socket_fd=connfd;
1896 demux[xtra_demux_id].rdr=NULL;
1897 demux[xtra_demux_id].pidindex=-1;
1898
1899 //add streams to xtra demux
1900 for(k = 0; k < demux[demux_id].STREAMpidcount; ++k){
1901 if(!demux[demux_id].ECMpids[j].streams || demux[demux_id].ECMpids[j].streams & (1 << k)){
1902 demux[xtra_demux_id].ECMpids[0].streams |= (1 << demux[xtra_demux_id].STREAMpidcount);
1903 demux[xtra_demux_id].STREAMpids[demux[xtra_demux_id].STREAMpidcount] = demux[demux_id].STREAMpids[k];
1904 ++demux[xtra_demux_id].STREAMpidcount;
1905
1906 //shift stream associations in normal demux because we will remove the stream entirely
1907 for(l = 0; l < demux[demux_id].ECMpidcount; ++l){
1908 for(m = k; m < demux[demux_id].STREAMpidcount-1; ++m){
1909 if(demux[demux_id].ECMpids[l].streams & (1 << (m+1))){
1910 demux[demux_id].ECMpids[l].streams |= (1 << m);
1911 } else {
1912 demux[demux_id].ECMpids[l].streams &= ~(1 << m);
1913 }
1914 }
1915 }
1916 // remove stream association from normal demux device
1917 for(l = k; l < demux[demux_id].STREAMpidcount-1; ++l){
1918 demux[demux_id].STREAMpids[l] = demux[demux_id].STREAMpids[l+1];
1919 }
1920 --demux[demux_id].STREAMpidcount;
1921 --k;
1922 }
1923 }
1924
1925 //remove ecmpid from normal demuxer
1926 for(k = j; k < demux[demux_id].ECMpidcount; ++k){
1927 demux[demux_id].ECMpids[k] = demux[demux_id].ECMpids[k+1];
1928 }
1929 --demux[demux_id].ECMpidcount;
1930 --j;
1931 if(demux[xtra_demux_id].STREAMpidcount > 0){
1932 dvbapi_start_descrambling(xtra_demux_id);
1933 dvbapi_try_next_caid(xtra_demux_id);
1934 } else {
1935 cs_log("[pmt] Found no streams for xtra demuxer. Not starting additional decoding on it.");
1936 }
1937 if(demux[demux_id].STREAMpidcount < 1){
1938 cs_log("[pmt] Found no streams for normal demuxer. Not starting additional decoding on it.");
1939 return xtra_demux_id;
1940 }
1941 }
1942 }
1943
1944#if defined WITH_AZBOX || defined WITH_MCA
1945 openxcas_sid = program_number;
1946#endif
1947
1948 if (ca_pmt_list_management == 0x05) {
1949 if (demux[demux_id].curindex==-1) {
1950 dvbapi_resort_ecmpids(demux_id);
1951 dvbapi_try_next_caid(demux_id);
1952 } else
1953 dvbapi_start_descrambling(demux_id);
1954 } else if (demux[demux_id].ECMpidcount>0 && ca_pmt_list_management != 0x01) {
1955 dvbapi_resort_ecmpids(demux_id);
1956 dvbapi_try_next_caid(demux_id);
1957 } else {
1958 // set channel srvid+caid
1959 dvbapi_client->last_srvid = demux[demux_id].program_number;
1960 dvbapi_client->last_caid = 0;
1961 // reset idle-Time
1962 dvbapi_client->last=time((time_t*)0);
1963 }
1964
1965 return demux_id;
1966}
1967
1968
1969void dvbapi_handlesockmsg (unsigned char *buffer, uint32_t len, int32_t connfd) {
1970 uint32_t val=0, size=0, i, k;
1971
1972 //cs_dump(buffer, len, "handlesockmsg:");
1973 for (k = 0; k < len; k += 3 + size + val) {
1974 if (buffer[0+k] != 0x9F || buffer[1+k] != 0x80) {
1975 cs_debug_mask(D_DVBAPI,"unknown socket command: %02x", buffer[0+k]);
1976 return;
1977 }
1978
1979 if (k>0) {
1980 cs_log("Unsupported capmt. Please report");
1981 cs_dump(buffer, len, "capmt:");
1982 }
1983
1984 if (buffer[3+k] & 0x80) {
1985 val = 0;
1986 size = buffer[3+k] & 0x7F;
1987 for (i = 0; i < size; i++)
1988 val = (val << 8) | buffer[i + 1 + 3 + k];
1989 size++;
1990 } else {
1991 val = buffer[3+k] & 0x7F;
1992 size = 1;
1993 }
1994 switch(buffer[2+k]) {
1995 case 0x32:
1996 dvbapi_parse_capmt(buffer + size + 3 + k, val, connfd, NULL);
1997 break;
1998 case 0x3f:
1999 //9F 80 3f 04 83 02 00 <demux index>
2000 cs_ddump_mask(D_DVBAPI, buffer, len, "capmt 3f:");
2001 // ipbox fix
2002 if (cfg.dvbapi_boxtype==BOXTYPE_IPBOX) {
2003 int32_t demux_index=buffer[7+k];
2004 for (i = 0; i < MAX_DEMUX; i++) {
2005 if (demux[i].demux_index == demux_index) {
2006 dvbapi_stop_descrambling(i);
2007 break;
2008 }
2009 }
2010 // check do we have any demux running on this fd
2011 int16_t execlose = 1;
2012 for (i = 0; i < MAX_DEMUX; i++) {
2013 if (demux[i].socket_fd == connfd) {
2014 execlose = 0;
2015 break;
2016 }
2017 }
2018 if (execlose) close(connfd);
2019 } else {
2020 close(connfd);
2021 }
2022 break;
2023 default:
2024 cs_debug_mask(D_DVBAPI,"handlesockmsg() unknown command");
2025 cs_dump(buffer, len, "unknown command:");
2026 break;
2027 }
2028 }
2029}
2030
2031int32_t dvbapi_init_listenfd(void) {
2032 int32_t clilen,listenfd;
2033 struct sockaddr_un servaddr;
2034
2035 memset(&servaddr, 0, sizeof(struct sockaddr_un));
2036 servaddr.sun_family = AF_UNIX;
2037 cs_strncpy(servaddr.sun_path, devices[selected_box].cam_socket_path, sizeof(servaddr.sun_path));
2038 clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
2039
2040 if ((unlink(devices[selected_box].cam_socket_path) < 0) && (errno != ENOENT))
2041 return 0;
2042 if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
2043 return 0;
2044 if (bind(listenfd, (struct sockaddr *)&servaddr, clilen) < 0)
2045 return 0;
2046 if (listen(listenfd, 5) < 0)
2047 return 0;
2048 // change the access right on the camd.socket
2049 // this will allow oscam to run as root if needed
2050 // and still allow non root client to connect to the socket
2051
2052 chmod(devices[selected_box].cam_socket_path, S_IRWXU | S_IRWXG | S_IRWXO);
2053
2054 return listenfd;
2055}
2056
2057pthread_mutex_t event_handler_lock;
2058
2059void event_handler(int32_t UNUSED(signal)) {
2060 struct stat pmt_info;
2061 char dest[1024];
2062 DIR *dirp;
2063 struct dirent entry, *dp = NULL;
2064 int32_t i, pmt_fd;
2065 uchar mbuf[1024];
2066
2067 if (dvbapi_client != cur_client()) return;
2068
2069 pthread_mutex_lock(&event_handler_lock);
2070
2071 if (cfg.dvbapi_boxtype == BOXTYPE_PC)
2072 pausecam = 0;
2073 else {
2074 int32_t standby_fd = open(STANDBY_FILE, O_RDONLY);
2075 pausecam = (standby_fd > 0) ? 1 : 0;
2076 if (standby_fd) close(standby_fd);
2077 }
2078
2079 if (cfg.dvbapi_boxtype==BOXTYPE_IPBOX || cfg.dvbapi_pmtmode == 1) {
2080 pthread_mutex_unlock(&event_handler_lock);
2081 return;
2082 }
2083
2084 for (i=0;i<MAX_DEMUX;i++) {
2085 if (demux[i].pmt_file[0] != 0) {
2086 snprintf(dest, sizeof(dest), "%s%s", TMPDIR, demux[i].pmt_file);
2087 pmt_fd = open(dest, O_RDONLY);
2088 if(pmt_fd>0) {
2089 if (fstat(pmt_fd, &pmt_info) != 0) {
2090 close(pmt_fd);
2091 continue;
2092 }
2093
2094 if ((time_t)pmt_info.st_mtime != demux[i].pmt_time) {
2095 cs_log("Stopping demux for pmt file %s", dest);
2096 dvbapi_stop_descrambling(i);
2097 }
2098
2099 close(pmt_fd);
2100 continue;
2101 } else {
2102 cs_log("Stopping demux for pmt file %s", dest);
2103 dvbapi_stop_descrambling(i);
2104 }
2105 }
2106 }
2107
2108 if (disable_pmt_files) {
2109 pthread_mutex_unlock(&event_handler_lock);
2110 return;
2111 }
2112
2113 dirp = opendir(TMPDIR);
2114 if (!dirp) {
2115 cs_debug_mask(D_DVBAPI,"opendir failed (errno=%d %s)", errno, strerror(errno));
2116 pthread_mutex_unlock(&event_handler_lock);
2117 return;
2118 }
2119
2120 while (!cs_readdir_r(dirp, &entry, &dp)) {
2121 if (!dp) break;
2122
2123 if (strlen(dp->d_name) < 7)
2124 continue;
2125 if (strncmp(dp->d_name, "pmt", 3)!=0 || strncmp(dp->d_name+strlen(dp->d_name)-4, ".tmp", 4)!=0)
2126 continue;
2127
2128 snprintf(dest, sizeof(dest), "%s%s", TMPDIR, dp->d_name);
2129 pmt_fd = open(dest, O_RDONLY);
2130 if (pmt_fd < 0)
2131 continue;
2132
2133 if (fstat(pmt_fd, &pmt_info) != 0)
2134 { close(pmt_fd); continue; }
2135
2136 int32_t found=0;
2137 for (i=0;i<MAX_DEMUX;i++) {
2138 if (strcmp(demux[i].pmt_file, dp->d_name)==0) {
2139 if ((time_t)pmt_info.st_mtime == demux[i].pmt_time) {
2140 found=1;
2141 continue;
2142 }
2143 dvbapi_stop_descrambling(i);
2144 }
2145 }
2146 if (found)
2147 { close(pmt_fd); continue; }
2148
2149 cs_debug_mask(D_DVBAPI,"found pmt file %s", dest);
2150 cs_sleepms(100);
2151
2152 uint32_t len = read(pmt_fd,mbuf,sizeof(mbuf));
2153 close(pmt_fd);
2154
2155 if (len < 1) {
2156 cs_debug_mask(D_DVBAPI,"pmt file %s have invalid len!", dest);
2157 continue;
2158 }
2159
2160 int32_t pmt_id;
2161#ifdef QBOXHD
2162 uint32_t j1,j2;
2163 // QboxHD pmt.tmp is the full capmt written as a string of hex values
2164 // pmt.tmp must be longer than 3 bytes (6 hex chars) and even length
2165 if ((len<6) || ((len%2) != 0) || ((len/2)>sizeof(dest))) {
2166 cs_debug_mask(D_DVBAPI,"error parsing QboxHD pmt.tmp, incorrect length");
2167 continue;
2168 }
2169
2170 for(j2=0,j1=0;j2<len;j2+=2,j1++) {
2171 if (sscanf((char*)mbuf+j2, "%02X", (unsigned int*)dest+j1) != 1) {
2172 cs_debug_mask(D_DVBAPI,"error parsing QboxHD pmt.tmp, data not valid in position %d",j2);
2173 pthread_mutex_unlock(&event_handler_lock);
2174 return;
2175 }
2176 }
2177
2178 cs_ddump_mask(D_DVBAPI, (unsigned char *)dest, len/2, "QboxHD pmt.tmp:");
2179
2180 pmt_id = dvbapi_parse_capmt((unsigned char *)dest+4, (len/2)-4, -1, dp->d_name);
2181#else
2182 if (len>sizeof(dest)) {
2183 cs_debug_mask(D_DVBAPI,"event_handler() dest buffer is to small for pmt data!");
2184 continue;
2185 }
2186 cs_ddump_mask(D_DVBAPI, mbuf,len,"pmt:");
2187
2188 dest[0] = 0x03;
2189 dest[1] = mbuf[3];
2190 dest[2] = mbuf[4];
2191
2192 i2b_buf(2, (((mbuf[10] & 0x0F) << 8) | mbuf[11])+1, (uchar*)dest+4);
2193 dest[6] = 0;
2194
2195 memcpy(dest + 7, mbuf + 12, len - 12 - 4);
2196
2197 pmt_id = dvbapi_parse_capmt((uchar*)dest, 7 + len - 12 - 4, -1, dp->d_name);
2198#endif
2199 if (pmt_id>=0) {
2200 cs_strncpy(demux[pmt_id].pmt_file, dp->d_name, sizeof(demux[pmt_id].pmt_file));
2201 demux[pmt_id].pmt_time = (time_t)pmt_info.st_mtime;
2202 }
2203
2204 if (cfg.dvbapi_pmtmode == 3) {
2205 disable_pmt_files=1;
2206 break;
2207 }
2208 }
2209 closedir(dirp);
2210 pthread_mutex_unlock(&event_handler_lock);
2211}
2212
2213void *dvbapi_event_thread(void *cli) {
2214 struct s_client * client = (struct s_client *) cli;
2215 pthread_setspecific(getclient, client);
2216 set_thread_name(__func__);
2217 while(1) {
2218 cs_sleepms(750);
2219 event_handler(0);
2220 }
2221
2222 return NULL;
2223}
2224
2225void dvbapi_process_input(int32_t demux_id, int32_t filter_num, uchar *buffer, int32_t len) {
2226 struct s_ecmpids *curpid = &demux[demux_id].ECMpids[demux[demux_id].demux_fd[filter_num].pidindex];
2227 uint16_t chid = 0;
2228
2229 if (cfg.dvbapi_au>0) // start emm filter!
2230 dvbapi_start_emm_filter(demux_id);
2231
2232 if (pausecam)
2233 return;
2234
2235 struct s_dvbapi_priority *p;
2236 for (p = dvbapi_priority; p != NULL; p = p->next) {
2237 if (p->type != 'l') continue;
2238
2239 if (p->caid && p->caid != curpid->CAID) continue;
2240 if (p->provid && p->provid != curpid->PROVID) continue;
2241 if (p->ecmpid && p->ecmpid != curpid->ECM_PID) continue;
2242 if (p->srvid && p->srvid != demux[demux_id].program_number) continue;
2243
2244 if (p->delay == len && p->force < 6) {
2245 p->force++;
2246 return;
2247 }
2248 if (p->force >= 6)
2249 p->force=0;
2250 }
2251
2252 if (demux[demux_id].demux_fd[filter_num].type==TYPE_ECM) {
2253 if (len != (((buffer[1] & 0xf) << 8) | buffer[2]) + 3) //invaild CAT length
2254 return;
2255
2256 if (buffer[0] != 0x80 && buffer[0] != 0x81)
2257 return;
2258
2259 uint16_t caid = curpid->CAID;
2260 uint32_t provid = curpid->PROVID;
2261
2262 if ((caid >> 8) == 0x06) {
2263 //80 70 39 53 04 05 00 88
2264 if (buffer[5]>20) return;
2265 if (curpid->irdeto_numchids != buffer[5]+1) {
2266 cs_debug_mask(D_DVBAPI,"Found %d IRDETO ECM CHIDs", buffer[5]+1);
2267 curpid->irdeto_numchids = buffer[5]+1;
2268 curpid->irdeto_curchid = 0;
2269 curpid->irdeto_cycle = 0;
2270 curpid->irdeto_chids = 0;
2271 if (demux[demux_id].demux_fd[filter_num].count && (demux[demux_id].demux_fd[filter_num].count < (curpid->irdeto_numchids * 3)))
2272 demux[demux_id].demux_fd[filter_num].count = curpid->irdeto_numchids * 3;
2273 }
2274
2275 if (curpid->irdeto_curchid+1 > curpid->irdeto_numchids) {
2276 curpid->irdeto_cycle++;
2277 curpid->irdeto_curchid = 0;
2278 }
2279
2280 if (buffer[4] != curpid->irdeto_curchid) {
2281 //wait for the correct chid
2282 return;
2283 }
2284
2285 chid = (buffer[6] << 8) | buffer[7];
2286 if (demux[demux_id].pidindex==-1) {
2287 int8_t i = 0, found = 0;
2288
2289 for (p=dvbapi_priority, i=0; p != NULL && curpid->irdeto_cycle > -1; p = p->next) {
2290 if (p->type != 'p' && p->type != 'i') continue;
2291
2292 if (!p->chid) continue;
2293
2294 if (p->caid && p->caid != curpid->CAID) continue;
2295 if (p->provid && p->provid != curpid->PROVID) continue;
2296 if (p->ecmpid && p->ecmpid != curpid->ECM_PID) continue;
2297 if (p->srvid && p->srvid != demux[demux_id].program_number) continue;
2298
2299 if (p->type == 'i' && p->chid == chid) {
2300 curpid->irdeto_chids |= (1<<curpid->irdeto_curchid);
2301 curpid->irdeto_curchid++;
2302 return;
2303 } else if (p->type == 'i')
2304 continue;
2305
2306 if (i++ != curpid->irdeto_cycle)
2307 continue;
2308
2309 if (p->chid == chid) {
2310 found=1;
2311 break;
2312 } else {
2313 curpid->irdeto_curchid++;
2314 return;
2315 }
2316 }
2317
2318 if (!found && curpid->irdeto_cycle > -1) {
2319 curpid->irdeto_cycle = -1;
2320 curpid->irdeto_curchid = 0;
2321 return;
2322 }
2323
2324 if (curpid->irdeto_curchid+1 > curpid->irdeto_numchids)
2325 return;
2326 }
2327 curpid->irdeto_chids |= (1<<curpid->irdeto_curchid);
2328 }
2329
2330 if (curpid->table == buffer[0])
2331 return;
2332
2333 curpid->table = buffer[0];
2334
2335 if (!provid)
2336 provid = chk_provid(buffer, caid);
2337
2338 if (provid != curpid->PROVID)
2339 curpid->PROVID = provid;
2340
2341 ECM_REQUEST *er;
2342 if (!(er=get_ecmtask()))
2343 return;
2344
2345 er->srvid = demux[demux_id].program_number;
2346
2347 er->tsid = demux[demux_id].tsid;
2348 er->onid = demux[demux_id].onid;
2349 er->ens = demux[demux_id].enigma_namespace;
2350
2351 er->caid = caid;
2352 er->pid = curpid->ECM_PID;
2353 er->prid = provid;
2354 er->chid = chid;
2355 er->ecmlen= len;
2356 memcpy(er->ecm, buffer, er->ecmlen);
2357
2358 request_cw(dvbapi_client, er);
2359
2360 if (demux[demux_id].demux_fd[filter_num].count==1) {
2361 cs_debug_mask(D_DVBAPI, "auto disable filter #%d", filter_num);
2362 dvbapi_stop_filternum(demux_id, filter_num);
2363 }
2364 if (demux[demux_id].demux_fd[filter_num].count>1) {
2365 demux[demux_id].demux_fd[filter_num].count--;
2366 }
2367 }
2368 if (demux[demux_id].demux_fd[filter_num].type==TYPE_EMM) {
2369 if (buffer[0]==0x01) { //CAT
2370 cs_debug_mask(D_DVBAPI, "receiving cat");
2371 dvbapi_parse_cat(demux_id, buffer, len);
2372
2373 dvbapi_stop_filternum(demux_id, filter_num);
2374 return;
2375 }
2376 dvbapi_process_emm(demux_id, filter_num, buffer, len);
2377 }
2378
2379 //emm filter iteration
2380 if (!ll_emm_active_filter)
2381 ll_emm_active_filter = ll_create("ll_emm_active_filter");
2382
2383 if (!ll_emm_inactive_filter)
2384 ll_emm_inactive_filter = ll_create("ll_emm_inactive_filter");
2385
2386 if (!ll_emm_pending_filter)
2387 ll_emm_pending_filter = ll_create("ll_emm_pending_filter");
2388
2389 uint32_t filter_count = ll_count(ll_emm_active_filter)+ll_count(ll_emm_inactive_filter);
2390 if (demux[demux_id].max_emm_filter > 0 && ll_count(ll_emm_inactive_filter) > 0 && filter_count > demux[demux_id].max_emm_filter) {
2391 int32_t filter_queue = ll_count(ll_emm_inactive_filter);
2392 int32_t stopped=0, started=0;
2393 time_t now = time((time_t *) 0);
2394 struct s_emm_filter *filter_item;
2395 LL_ITER itr;
2396 itr = ll_iter_create(ll_emm_active_filter);
2397 while ((filter_item=ll_iter_next(&itr))) {
2398 if (!ll_count(ll_emm_inactive_filter) || (started == filter_queue))
2399 break;
2400 if (abs(now-filter_item->time_started) > 45) {
2401 struct s_dvbapi_priority *forceentry=dvbapi_check_prio_match_emmpid(filter_item->demux_id, filter_item->caid,
2402 filter_item->provid, 'p');
2403 if (!forceentry || (forceentry && !forceentry->force)) {
2404 cs_debug_mask(D_DVBAPI,"[EMM Filter] removing emm filter %i num %i on demux index %i",
2405 filter_item->count, filter_item->num, filter_item->demux_id);
2406 dvbapi_stop_filternum(filter_item->demux_id, filter_item->num);
2407 ll_iter_remove_data(&itr);
2408 add_emmfilter_to_list(filter_item->demux_id, filter_item->filter, filter_item->caid,
2409 filter_item->provid, filter_item->pid, filter_item->count, -1, 0);
2410 stopped++;
2411 }
2412 }
2413 if (stopped>started) {
2414 struct s_emm_filter *filter_item2;
2415 LL_ITER itr2 = ll_iter_create(ll_emm_inactive_filter);
2416 while ((filter_item2=ll_iter_next(&itr2))) {
2417 cs_ddump_mask(D_DVBAPI, filter_item2->filter, 32, "[EMM Filter] starting emm filter %i, pid: 0x%04X on demux index %i",
2418 filter_item2->count, filter_item2->pid, filter_item2->demux_id);
2419 dvbapi_set_filter(filter_item2->demux_id, selected_api, filter_item2->pid, filter_item2->caid,
2420 filter_item2->provid, filter_item2->filter, filter_item2->filter+16, 0,
2421 demux[filter_item2->demux_id].pidindex, filter_item2->count, TYPE_EMM, 1);
2422 ll_iter_remove_data(&itr2);
2423 started++;
2424 break;
2425 }
2426 }
2427 }
2428 itr = ll_iter_create(ll_emm_pending_filter);
2429 while ((filter_item=ll_iter_next(&itr))) {
2430 add_emmfilter_to_list(filter_item->demux_id, filter_item->filter, filter_item->caid,
2431 filter_item->provid, filter_item->pid, filter_item->count, 0, 0);
2432 ll_iter_remove_data(&itr);
2433 }
2434 }
2435}
2436
2437static void * dvbapi_main_local(void *cli) {
2438#ifdef WITH_AZBOX
2439 return azbox_main_thread(cli);
2440#endif
2441#ifdef WITH_MCA
2442 return mca_main_thread(cli);
2443#endif
2444
2445 struct s_client * client = (struct s_client *) cli;
2446 client->thread=pthread_self();
2447 pthread_setspecific(getclient, cli);
2448
2449 dvbapi_client=cli;
2450
2451 int32_t maxpfdsize=(MAX_DEMUX*MAX_FILTER)+MAX_DEMUX+2;
2452 struct pollfd pfd2[maxpfdsize];
2453 int32_t i,rc,pfdcount,g,connfd,clilen,j;
2454 int32_t ids[maxpfdsize], fdn[maxpfdsize], type[maxpfdsize];
2455 struct sockaddr_un servaddr;
2456 ssize_t len=0;
2457 uchar mbuf[1024];
2458
2459 struct s_auth *account;
2460 int32_t ok=0;
2461 for (account = cfg.account; account; account=account->next) {
2462 if ((ok = streq(cfg.dvbapi_usr, account->usr)))
2463 break;
2464 }
2465 cs_auth_client(client, ok ? account : (struct s_auth *)(-1), "dvbapi");
2466
2467 memset(demux, 0, sizeof(struct demux_s) * MAX_DEMUX);
2468 memset(ca_fd, 0, sizeof(ca_fd));
2469
2470 dvbapi_read_priority();
2471 dvbapi_detect_api();
2472
2473 if (selected_box == -1 || selected_api==-1) {
2474 cs_log("ERROR: Could not detect DVBAPI version.");
2475 return NULL;
2476 }
2477
2478 if (cfg.dvbapi_pmtmode == 1)
2479 disable_pmt_files=1;
2480
2481 int32_t listenfd = -1;
2482 if (cfg.dvbapi_boxtype != BOXTYPE_IPBOX_PMT && cfg.dvbapi_pmtmode != 2 && cfg.dvbapi_pmtmode != 5) {
2483 listenfd = dvbapi_init_listenfd();
2484 if (listenfd < 1) {
2485 cs_log("ERROR: Could not init camd.socket.");
2486 return NULL;
2487 }
2488 }
2489
2490 pthread_mutex_init(&event_handler_lock, NULL);
2491
2492 if (cfg.dvbapi_pmtmode != 4 && cfg.dvbapi_pmtmode != 5) {
2493 struct sigaction signal_action;
2494 signal_action.sa_handler = event_handler;
2495 sigemptyset(&signal_action.sa_mask);
2496 signal_action.sa_flags = SA_RESTART;
2497 sigaction(SIGRTMIN + 1, &signal_action, NULL);
2498
2499 dir_fd = open(TMPDIR, O_RDONLY);
2500 if (dir_fd >= 0) {
2501 fcntl(dir_fd, F_SETSIG, SIGRTMIN + 1);
2502 fcntl(dir_fd, F_NOTIFY, DN_MODIFY | DN_CREATE | DN_DELETE | DN_MULTISHOT);
2503 event_handler(SIGRTMIN + 1);
2504 }
2505 } else {
2506 pthread_t event_thread;
2507 int32_t ret = pthread_create(&event_thread, NULL, dvbapi_event_thread, (void*) dvbapi_client);
2508 if(ret){
2509 cs_log("ERROR: Can't create dvbapi event thread (errno=%d %s)", ret, strerror(ret));
2510 return NULL;
2511 } else
2512 pthread_detach(event_thread);
2513 }
2514
2515
2516 pfd2[0].fd = listenfd;
2517 pfd2[0].events = (POLLIN | POLLPRI);
2518 type[0]=1;
2519#ifdef WITH_COOLAPI
2520 system("pzapit -rz");
2521#endif
2522 while (1) {
2523 pfdcount = (listenfd > -1) ? 1 : 0;
2524
2525 for (i=0;i<MAX_DEMUX;i++) {
2526 for (g=0;g<MAX_FILTER;g++) {
2527 if (demux[i].demux_fd[g].fd>0 && selected_api != STAPI && selected_api != COOLAPI) {
2528 pfd2[pfdcount].fd = demux[i].demux_fd[g].fd;
2529 pfd2[pfdcount].events = (POLLIN | POLLPRI);
2530 ids[pfdcount]=i;
2531 fdn[pfdcount]=g;
2532 type[pfdcount++]=0;
2533 }
2534 }
2535
2536 if (demux[i].socket_fd>0) {
2537 rc=0;
2538 if (cfg.dvbapi_boxtype==BOXTYPE_IPBOX) {
2539 for (j = 0; j < pfdcount; j++) {
2540 if (pfd2[j].fd == demux[i].socket_fd) {
2541 rc=1;
2542 break;
2543 }
2544 }
2545 if (rc==1) continue;
2546 }
2547
2548 pfd2[pfdcount].fd=demux[i].socket_fd;
2549 pfd2[pfdcount].events = (POLLIN | POLLPRI | POLLHUP);
2550 ids[pfdcount]=i;
2551 type[pfdcount++]=1;
2552 }
2553 }
2554
2555 rc = poll(pfd2, pfdcount, 500);
2556 if (rc<1) continue;
2557
2558 for (i = 0; i < pfdcount; i++) {
2559 if (pfd2[i].revents > 3)
2560 cs_debug_mask(D_DVBAPI, "event %d on fd %d", pfd2[i].revents, pfd2[i].fd);
2561
2562 if (pfd2[i].revents & (POLLHUP | POLLNVAL)) {
2563 if (type[i]==1) {
2564 for (j=0;j<MAX_DEMUX;j++) {
2565 if (demux[j].socket_fd==pfd2[i].fd) {
2566 dvbapi_stop_descrambling(j);
2567 }
2568 }
2569 close(pfd2[i].fd);
2570 continue;
2571 }
2572 }
2573 if (pfd2[i].revents & (POLLIN | POLLPRI)) {
2574 if (type[i]==1) {
2575 if (pfd2[i].fd==listenfd) {
2576 clilen = sizeof(servaddr);
2577 connfd = accept(listenfd, (struct sockaddr *)&servaddr, (socklen_t *)&clilen);
2578 cs_debug_mask(D_DVBAPI, "new socket connection fd: %d", connfd);
2579
2580 disable_pmt_files=1;
2581
2582 if (connfd <= 0) {
2583 cs_debug_mask(D_DVBAPI,"accept() returns error on fd event %d (errno=%d %s)", pfd2[i].revents, errno, strerror(errno));
2584 continue;
2585 }
2586 } else {
2587 cs_debug_mask(D_DVBAPI, "PMT Update on socket %d.", pfd2[i].fd);
2588 connfd = pfd2[i].fd;
2589 }
2590
2591 len = read(connfd, mbuf, sizeof(mbuf));
2592
2593 if (len < 3) {
2594 cs_debug_mask(D_DVBAPI, "camd.socket: too small message received");
2595 continue;
2596 }
2597
2598 dvbapi_handlesockmsg(mbuf, len, connfd);
2599 } else { // type==0
2600 int32_t demux_index=ids[i];
2601 int32_t n=fdn[i];
2602
2603 if ((len=dvbapi_read_device(pfd2[i].fd, mbuf, sizeof(mbuf))) <= 0) {
2604 if (demux[demux_index].pidindex==-1) {
2605 dvbapi_try_next_caid(demux_index);
2606 }
2607 continue;
2608 }
2609
2610 if (pfd2[i].fd==(int)demux[demux_index].demux_fd[n].fd) {
2611 dvbapi_process_input(demux_index,n,mbuf,len);
2612 }
2613 }
2614 }
2615 }
2616 }
2617 return NULL;
2618}
2619
2620void dvbapi_write_cw(int32_t demux_id, uchar *cw, int32_t idx) {
2621 int32_t n;
2622 int8_t cwEmpty = 0;
2623 unsigned char nullcw[8];
2624 memset(nullcw, 0, 8);
2625 ca_descr_t ca_descr;
2626 memset(&ca_descr,0,sizeof(ca_descr));
2627 if(memcmp(demux[demux_id].lastcw[0],nullcw,8)==0 && memcmp(demux[demux_id].lastcw[1],nullcw,8)==0) cwEmpty = 1; // to make sure that both cws get written on constantcw
2628
2629 for (n=0;n<2;n++) {
2630 char lastcw[9*3];
2631 char newcw[9*3];
2632 cs_hexdump(0, demux[demux_id].lastcw[n], 8, lastcw, sizeof(lastcw));
2633 cs_hexdump(0, cw+(n*8), 8, newcw, sizeof(newcw));
2634 if (((memcmp(cw+(n*8),demux[demux_id].lastcw[0],8)!=0 && memcmp(cw+(n*8),demux[demux_id].lastcw[1],8)!=0) || cwEmpty) && memcmp(cw+(n*8),nullcw,8)!=0) { // check if already delivered and new cw part is valid!
2635 ca_descr.index = idx;
2636 ca_descr.parity = n;
2637 cs_debug_mask(D_DVBAPI,"writing %s part (%s) of controlword, replacing expired (%s)",(n == 1?"odd":"even"), newcw, lastcw);
2638 memcpy(demux[demux_id].lastcw[n],cw+(n*8),8);
2639 memcpy(ca_descr.cw,cw+(n*8),8);
2640#ifdef WITH_COOLAPI
2641 cs_debug_mask(D_DVBAPI, "write cw%d index: %d (ca_mask %d)", n, ca_descr.index, demux[demux_id].ca_mask);
2642 coolapi_write_cw(demux[demux_id].ca_mask, demux[demux_id].STREAMpids, demux[demux_id].STREAMpidcount, &ca_descr);
2643#else
2644 int32_t i;
2645 for (i=0;i<8;i++) {
2646 if (demux[demux_id].ca_mask & (1 << i)) {
2647 cs_debug_mask(D_DVBAPI, "write cw%d index: %d (ca%d)", n, ca_descr.index, i);
2648 if (ca_fd[i]<=0) {
2649 if (cfg.dvbapi_boxtype == BOXTYPE_PC)
2650 ca_fd[i]=dvbapi_open_netdevice(1, i, demux[demux_id].adapter_index);
2651 else
2652 ca_fd[i]=dvbapi_open_device(1, i, demux[demux_id].adapter_index);
2653 if (ca_fd[i]<=0)
2654 return;
2655 }
2656
2657 if (cfg.dvbapi_boxtype == BOXTYPE_PC) {
2658 // preparing packet
2659 int32_t request = CA_SET_DESCR;
2660 unsigned char packet[sizeof(request) + sizeof(ca_descr)];
2661 memcpy(&packet, &request, sizeof(request));
2662 memcpy(&packet[sizeof(request)], &ca_descr, sizeof(ca_descr));
2663
2664 // sending data
2665 send(ca_fd[i], &packet, sizeof(packet), 0);
2666 } else {
2667 if (ioctl(ca_fd[i], CA_SET_DESCR, &ca_descr) < 0)
2668 cs_log("ERROR: ioctl(CA_SET_DESCR): %s", strerror(errno));
2669 }
2670 }
2671 }
2672#endif
2673 }
2674 }
2675}
2676
2677void delayer(ECM_REQUEST *er)
2678{
2679 if (cfg.dvbapi_delayer <= 0) return;
2680
2681 struct timeb tpe;
2682 cs_ftime(&tpe);
2683 int32_t t = 1000 * (tpe.time-er->tps.time) + tpe.millitm-er->tps.millitm;
2684 if (t < cfg.dvbapi_delayer) {
2685 cs_debug_mask(D_DVBAPI, "delayer: t=%dms, cfg=%dms -> delay=%dms", t, cfg.dvbapi_delayer, cfg.dvbapi_delayer-t);
2686 cs_sleepms(cfg.dvbapi_delayer-t);
2687 }
2688}
2689
2690void dvbapi_send_dcw(struct s_client *client, ECM_REQUEST *er)
2691{
2692#ifdef WITH_AZBOX
2693 azbox_send_dcw(client, er);
2694 return;
2695#endif
2696#ifdef WITH_MCA
2697 mca_send_dcw(client, er);
2698 return;
2699#endif
2700
2701 int32_t i,j;
2702
2703 for (i=0;i<MAX_DEMUX;i++) {
2704 if (demux[i].program_number==er->srvid) {
2705 demux[i].rdr=er->selected_reader;
2706
2707 for (j=0; j<demux[i].ECMpidcount; j++)
2708 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)
2709 break;
2710 if (j==demux[i].ECMpidcount) continue;
2711
2712 if (er->rc < E_NOTFOUND && cfg.dvbapi_requestmode==0 && (demux[i].pidindex==-1) && er->caid!=0) {
2713 edit_channel_cache(i, j, 1);
2714 dvbapi_start_descrambling(i);
2715 }
2716
2717 if (er->rc < E_NOTFOUND && cfg.dvbapi_requestmode==1 && (demux[i].pidindex==-1) && er->caid!=0 && demux[i].ECMpids[j].checked != 2) { //FOUND
2718
2719 int32_t num_pids=0, last_idx=j;
2720
2721 int32_t t;
2722 for (t=0;t<demux[i].ECMpidcount;t++) {
2723
2724 //check this FOUND for higher status:
2725 if (t!=j && demux[i].ECMpids[j].status >= demux[i].ECMpids[t].status) { //mark index t as low status
2726 demux[i].ECMpids[t].checked = 2;
2727 }
2728 if (demux[i].ECMpids[t].checked != 2) {
2729 num_pids++;
2730 last_idx=t;
2731 }
2732 }
2733
2734 int32_t o;
2735 for (o = 0; o < MAX_FILTER; o++) {
2736 if (demux[i].demux_fd[o].fd > 0) { //TESTME: ocaid for betatunnel added!
2737 if ((demux[i].demux_fd[o].pid == er->pid) && ((demux[i].demux_fd[o].caid == demux[i].ECMpids[last_idx].CAID ) || (demux[i].demux_fd[o].caid == er->ocaid)))
2738 demux[i].demux_fd[o].count = 0; //activate last_idx
2739 else
2740 dvbapi_stop_filternum(i, o);
2741 }
2742 }
2743 edit_channel_cache(i, j, 1);
2744
2745 demux[i].curindex = j;
2746 dvbapi_start_descrambling(i);
2747 }
2748 if (demux[i].pidindex != -1 && demux[i].curindex != j) {
2749 demux[i].curindex = j;
2750 //I hope this trick works for all: adjust the index to write the right cw:
2751 demux[i].ECMpids[j].index = demux[i].ECMpids[demux[i].pidindex].index;
2752 demux[i].ECMpids[demux[i].pidindex].index = 0; // reset this old index, it wont be used anymore!
2753 dvbapi_start_descrambling(i);
2754 }
2755 if (er->rc >= E_NOTFOUND) {
2756 edit_channel_cache(i, j, 0);
2757 if ((er->caid >> 8) == 0x06 && demux[i].ECMpids[j].irdeto_chids < (((0xFFFF<<(demux[i].ECMpids[j].irdeto_numchids)) ^ 0xFFFF) & 0xFFFF)) {
2758 demux[i].ECMpids[j].irdeto_curchid++;
2759 demux[i].ECMpids[j].table=0;
2760 cs_debug_mask(D_DVBAPI,"trying irdeto chid index: %d", demux[i].ECMpids[j].irdeto_curchid);
2761 return;
2762 }
2763 demux[i].ECMpids[j].irdeto_chids = 0;
2764 demux[i].ECMpids[j].irdeto_curchid = 0;
2765 demux[i].ECMpids[j].irdeto_cycle = 0;
2766 int8_t last_checked = demux[i].ECMpids[j].checked;
2767 demux[i].ECMpids[j].checked = 2;
2768
2769 if (demux[i].pidindex==-1) {
2770 if (cfg.dvbapi_requestmode == 1)
2771 return;
2772
2773 struct s_dvbapi_priority *forceentry=dvbapi_check_prio_match(i, demux[i].curindex, 'p');
2774 if (forceentry && forceentry->force)
2775 dvbapi_start_descrambling(i);
2776 else
2777 dvbapi_try_next_caid(i);
2778 } else {
2779 struct s_dvbapi_priority *forceentry=dvbapi_check_prio_match(i, demux[i].curindex, 'p');
2780 if (!forceentry || (forceentry && !forceentry->force)) {
2781 demux[i].curindex = 0;
2782 demux[i].pidindex = -1;
2783 dvbapi_try_next_caid(i);
2784 }
2785 else if (cfg.dvbapi_requestmode == 1) {
2786 int32_t t, num_pids;
2787 for (num_pids = 0, t = 0; t < demux[i].ECMpidcount;t++) {
2788 if (demux[i].ECMpids[t].checked != 2)
2789 num_pids++;
2790 }
2791 cs_debug_mask(D_DVBAPI, "request restarting num_pids=%d last_checked=%d", num_pids, last_checked);
2792
2793 if (!num_pids && last_checked == 1) { // we had rc=E_FOUND, but now we get a NOT_FOUND? Try all caids again:
2794 dvbapi_resort_ecmpids(i);
2795 dvbapi_try_next_caid(i);
2796 }
2797 }
2798 }
2799 return;
2800 }
2801
2802 struct s_dvbapi_priority *delayentry=dvbapi_check_prio_match(i, demux[i].pidindex, 'd');
2803 if (delayentry) {
2804 if (delayentry->delay<1000) {
2805 cs_debug_mask(D_DVBAPI, "wait %d ms", delayentry->delay);
2806 cs_sleepms(delayentry->delay);
2807 }
2808 }
2809
2810 delayer(er);
2811
2812 switch (selected_api) {
2813#ifdef WITH_STAPI
2814 case STAPI:
2815 stapi_write_cw(i, er->cw, demux[i].STREAMpids, demux[i].STREAMpidcount, demux[i].pmt_file);
2816 break;
2817#endif
2818 default:
2819 if (cfg.dvbapi_boxtype == BOXTYPE_NEUMO) {
2820 int32_t idx=0;
2821 sscanf(demux[i].pmt_file, "pmt%3d.tmp", &idx);
2822 dvbapi_write_cw(i, er->cw, idx);
2823 break;
2824 }
2825 dvbapi_write_cw(i, er->cw, demux[i].ECMpids[j].index-1);
2826 break;
2827 }
2828
2829 // reset idle-Time
2830 client->last=time((time_t*)0);
2831
2832 FILE *ecmtxt;
2833 ecmtxt = fopen(ECMINFO_FILE, "w");
2834 if(ecmtxt != NULL && er->rc < E_NOTFOUND) {
2835 char tmp[25];
2836 fprintf(ecmtxt, "caid: 0x%04X\npid: 0x%04X\nprov: 0x%06X\n", er->caid, er->pid, (uint) er->prid);
2837 switch (er->rc) {
2838 case 0:
2839 if (er->selected_reader) {
2840 fprintf(ecmtxt, "reader: %s\n", er->selected_reader->label);
2841 if (is_cascading_reader(er->selected_reader))
2842 fprintf(ecmtxt, "from: %s\n", er->selected_reader->device);
2843 else
2844 fprintf(ecmtxt, "from: local\n");
2845 fprintf(ecmtxt, "protocol: %s\n", reader_get_type_desc(er->selected_reader, 1));
2846 fprintf(ecmtxt, "hops: %d\n", er->selected_reader->currenthops);
2847 }
2848 break;
2849
2850 case 1:
2851 fprintf(ecmtxt, "reader: Cache\n");
2852 fprintf(ecmtxt, "from: cache1\n");
2853 fprintf(ecmtxt, "protocol: none\n");
2854 break;
2855
2856 case 2:
2857 fprintf(ecmtxt, "reader: Cache\n");
2858 fprintf(ecmtxt, "from: cache2\n");
2859 fprintf(ecmtxt, "protocol: none\n");
2860 break;
2861
2862 case 3:
2863 fprintf(ecmtxt, "reader: Cache\n");
2864 fprintf(ecmtxt, "from: cache3\n");
2865 fprintf(ecmtxt, "protocol: none\n");
2866 break;
2867 }
2868 fprintf(ecmtxt, "ecm time: %.3f\n", (float) client->cwlastresptime/1000);
2869 fprintf(ecmtxt, "cw0: %s\n", cs_hexdump(1,demux[i].lastcw[0],8, tmp, sizeof(tmp)));
2870 fprintf(ecmtxt, "cw1: %s\n", cs_hexdump(1,demux[i].lastcw[1],8, tmp, sizeof(tmp)));
2871 fclose(ecmtxt);
2872 ecmtxt = NULL;
2873 }
2874 if (ecmtxt) {
2875 fclose(ecmtxt);
2876 ecmtxt = NULL;
2877 }
2878
2879 }
2880 }
2881}
2882
2883static void * dvbapi_handler(struct s_client * cl, uchar* UNUSED(mbuf), int32_t module_idx) {
2884 //cs_log("dvbapi loaded fd=%d", idx);
2885 if (cfg.dvbapi_enabled == 1) {
2886 cl = create_client(get_null_ip());
2887 cl->module_idx = module_idx;
2888 cl->typ='c';
2889 int32_t ret = pthread_create(&cl->thread, NULL, dvbapi_main_local, (void*) cl);
2890 if(ret){
2891 cs_log("ERROR: Can't create dvbapi handler thread (errno=%d %s)", ret, strerror(ret));
2892 return NULL;
2893 } else
2894 pthread_detach(cl->thread);
2895 }
2896
2897 return NULL;
2898}
2899
2900/*
2901 * protocol structure
2902 */
2903
2904void module_dvbapi(struct s_module *ph)
2905{
2906 ph->desc="dvbapi";
2907 ph->type=MOD_CONN_SERIAL;
2908 ph->listenertype = LIS_DVBAPI;
2909 ph->s_handler=dvbapi_handler;
2910 ph->send_dcw=dvbapi_send_dcw;
2911}
2912#endif // HAVE_DVBAPI
Note: See TracBrowser for help on using the repository browser.