source: trunk/module-dvbapi.c@ 8376

Last change on this file since 8376 was 8376, checked in by gf, 9 years ago

Revert r8119 changes related to Viaccess EMM reassembly.

EMM reassembly should not know internal dvbapi client information.

The proper fix is to run reassembly on the local reader side and
remove it completely from the client side.

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