source: trunk/module-dvbapi.c@ 8377

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

cryptoworks/viaccess: Run EMM reassembly before writing EMM in the card.

Before this patch EMM reassembly was only run by the dvbapi client.

This means that any other client (via newcamd, cs378x, cccam) was
expected to perform its own EMM reassembly otherwise the card
was unable to write the EMMs that needed preprocessing (reassemblation).

This commit moves EMM reassembly where it belongs - just before the
EMM is written in the card. That simplifies client logic (no more
knowledge of EMM structure and types) and allows cards to be updated
via any network protocol as long as the client is not trying to be
smart and just sends us all EMM packets.

The changes were tested with SRG Swiss Viacess card and Digiturk
Cryptoworks card. In the both cards shared EMMs were written OK
while receiving them via cs378x protocol and tsdecrypt as client.

If a client sends already reassembled EMMs it also works.

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