source: trunk/module-dvbapi.c@ 11212

Last change on this file since 11212 was 11212, checked in by Gorgone Impertinence, 7 years ago

fix small bug with channelname on srvid2 for fta

  • Property svn:eol-style set to LF
File size: 225.6 KB
Line 
1#define MODULE_LOG_PREFIX "dvbapi"
2
3#include "globals.h"
4
5#ifdef HAVE_DVBAPI
6
7#include "module-dvbapi.h"
8#include "module-cacheex.h"
9#include "module-dvbapi-azbox.h"
10#include "module-dvbapi-mca.h"
11#include "module-dvbapi-coolapi.h"
12#include "module-dvbapi-stapi.h"
13#include "module-dvbapi-chancache.h"
14#include "module-stat.h"
15#include "oscam-chk.h"
16#include "oscam-client.h"
17#include "oscam-config.h"
18#include "oscam-ecm.h"
19#include "oscam-emm.h"
20#include "oscam-files.h"
21#include "oscam-net.h"
22#include "oscam-reader.h"
23#include "oscam-string.h"
24#include "oscam-time.h"
25#include "oscam-work.h"
26#include "reader-irdeto.h"
27#include "cscrypt/md5.h"
28
29extern int32_t exit_oscam;
30
31#if defined (__CYGWIN__)
32#define F_NOTIFY 0
33#define F_SETSIG 0
34#define DN_MODIFY 0
35#define DN_CREATE 0
36#define DN_DELETE 0
37#define DN_MULTISHOT 0
38#endif
39
40const char *streamtxt_00_to_1B[] = {
41 "Reserved", // 00
42 "Videostream (MPEG-1)", // 01
43 "Videostream (MPEG-2)", // 02
44 "Audiostream (MPEG-1)", // 03
45 "Audiostream (MPEG-2)", // 04
46 "Datastream (MPEG-2 tabled data)", // 05
47 "Data-/Audiostream (Subtitles/VBI and AC-3)", // 06
48 "Datastream (MHEG)", // 07
49 "Datastream (DSM CC)", // 08
50 "Conditional Access ", // 09
51 "Datastream (DSM CC)", // 0A
52 "Datastream (DSM CC)", // 0B
53 "Datastream (DSM CC)", // 0C
54 "Datastream (DSM CC)", // 0D
55 "Datastream (Auxiliary)", // 0E
56 "Audiostream (MPEG-2)", // 0F
57 "Videostream (MPEG-4 H.263)", // 10
58 "Audiostream (MPEG-4)", // 11
59 "Datastream (MPEG-4 FlexMux)", // 12
60 "Datastream (MPEG-4 FlexMux)", // 13
61 "Datastream (DSM CC)", // 14
62 "Datastream (Metadata)", // 15
63 "Datastream (Metadata)", // 16
64 "Datastream (DSM CC)", // 17
65 "Datastream (DSM CC)", // 18
66 "Datastream (Metadata)", // 19
67 "Datastream (IPMP)", // 1A
68 "Videostream (MPEG-4)", // 1B
69 };
70
71const char *streamtxt_80_to_87[] = {
72 "Video-/Audiostream (H.262/PCM)", // 80
73 "Audiostream (Dolby Digital)", // 81
74 "Data-/Audiostream (Subtitles/DTS6)", // 82
75 "Audiostream (Dolby TrueHD)", // 83
76 "Audiostream (Dolby Digital Plus)", // 84
77 "Audiostream (DTS 8)", // 85
78 "Audiostream (DTS 8 losless)", // 86
79 "Audiostream (Dolby Digital Plus)", // 87
80 };
81
82const char *get_streamtxt(uint8_t id)
83{
84 if(id <= 0x1B)
85 {
86 return streamtxt_00_to_1B[id];
87 }
88 else if(id == 0x24)
89 {
90 return "Videostream (H.265 Ultra HD video)";
91 }
92 else if(id == 0x42)
93 {
94 return "Videostream (Chinese Video Standard)";
95 }
96 else if(id >= 0x80 && id <= 0x87)
97 {
98 return streamtxt_80_to_87[id - 0x80];
99 }
100 else if(id == 0x90)
101 {
102 return "Datastream (Blu-ray subtitling)";
103 }
104 else if(id == 0x95)
105 {
106 return "Datastream (DSM CC)";
107 }
108 else if(id == 0xC0)
109 {
110 return "Datastream (DigiCipher II text)";
111 }
112 else if(id == 0xC2)
113 {
114 return "Datastream (DSM CC)";
115 }
116 else if(id == 0xD1)
117 {
118 return "Videostream (BBC Dirac Ultra HD video)";
119 }
120 else if(id == 0xEA)
121 {
122 return "Videostream (WMV9 lower bit-rate)";
123 }
124 else
125 {
126 return "Reserved";
127 }
128}
129
130
131void flush_read_fd(int32_t demux_index, int32_t num, int fd)
132{
133 if(!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX)
134 {
135 cs_log_dbg(D_DVBAPI,"Demuxer %d flushing stale input data of filter %d (fd:%d)", demux_index, num + 1, fd);
136 fd_set rd;
137 struct timeval t;
138 char buff[100];
139 t.tv_sec=0;
140 t.tv_usec=0;
141 FD_ZERO(&rd);
142 FD_SET(fd,&rd);
143 while(select(fd+1,&rd,NULL,NULL,&t) > 0)
144 {
145 if (read(fd,buff,100)){;}
146 }
147 }
148}
149
150static int dvbapi_ioctl(int fd, uint32_t request, ...)
151{
152 int ret = 0;
153 va_list args;
154 va_start(args, request);
155 if (!(cfg.dvbapi_boxtype == BOXTYPE_SAMYGO))
156 {
157 void *param = va_arg(args, void *);
158 ret = ioctl(fd, request, param);
159 }
160 else
161 {
162 switch(request)
163 {
164 case DMX_SET_FILTER:
165 {
166 struct dmx_sct_filter_params *sFP = va_arg(args, struct dmx_sct_filter_params *);
167
168 //fix filter for samygo
169 //note: we only have 14 available filter bytes (instead of 16) on samygo
170 memmove(&sFP->filter.filter[3], &sFP->filter.filter[1], 13);
171 memset(&sFP->filter.filter[1], 0, 2);
172
173 memmove(&sFP->filter.mask[3], &sFP->filter.mask[1], 13);
174 memset(&sFP->filter.mask[1], 0, 2);
175
176 // prepare packet
177 unsigned char packet[sizeof(request) + sizeof(struct dmx_sct_filter_params)];
178 memcpy(&packet, &request, sizeof(request));
179 memcpy(&packet[sizeof(request)], sFP, sizeof(struct dmx_sct_filter_params));
180 ret = send(fd, packet, sizeof(packet), 0);
181 break;
182 }
183 case DMX_SET_FILTER1:
184 {
185 cs_log("error: samygo does not support DMX_SET_FILTER1");
186 ret = -1;
187 break;
188 }
189 case DMX_STOP:
190 {
191 ret = send(fd, &request, sizeof(request), 0);
192 ret = 1;
193 break;
194 }
195 case CA_SET_PID:
196 {
197 ca_pid_t *ca_pid2 = va_arg(args, ca_pid_t *);
198
199 // preparing packet
200 unsigned char packet[sizeof(request) + sizeof(ca_pid_t)];
201 memcpy(&packet[0], &request, sizeof(request));
202 memcpy(&packet[sizeof(request)], ca_pid2, sizeof(ca_pid_t));
203
204 // sending data to UDP
205 ret = send(fd, &packet[0], sizeof(packet), 0);
206 break;
207 }
208 case CA_SET_DESCR:
209 {
210 ca_descr_t *ca_descr = va_arg(args, ca_descr_t *);
211
212 // preparing packet
213 unsigned char packet[sizeof(request) + sizeof(ca_descr_t)];
214 memcpy(&packet[0], &request, sizeof(request));
215 memcpy(&packet[sizeof(request)], ca_descr, sizeof(ca_descr_t));
216
217 // sending data to UDP
218 ret = send(fd, &packet[0], sizeof(packet), 0);
219 break;
220 }
221 case CA_SET_DESCR_MODE:
222 {
223 cs_log("error: samygo does not support CA_SET_DESCR_MODE");
224 ret = -1;
225 break;
226 }
227 }
228 if (ret > 0) // send() may return larger than 1
229 ret = 1;
230 }
231#if defined(__powerpc__)
232 // Old dm500 boxes (ppc old) are using broken kernel, se we need some fixups
233 switch (request)
234 {
235 case DMX_STOP:
236 case CA_SET_DESCR:
237 case CA_SET_PID:
238 ret = 1;
239 }
240#endif
241 // FIXME: Workaround for su980 bug
242 // See: http://www.streamboard.tv/wbb2/thread.php?postid=533940
243 if(boxtype_is("su980"))
244 ret = 1;
245 va_end(args);
246 return ret;
247}
248
249// tunemm_caid_map
250#define FROM_TO 0
251#define TO_FROM 1
252
253#if defined(CARDREADER_STAPI) || defined(CARDREADER_STAPI5)
254//fix from stapi5 patch
255int32_t pausecam = 0, disable_pmt_files = 0, pmt_stopmarking = 1;
256#else
257int32_t pausecam = 0, disable_pmt_files = 0, pmt_stopmarking = 0;
258#endif
259
260DEMUXTYPE demux[MAX_DEMUX];
261struct s_dvbapi_priority *dvbapi_priority;
262struct s_client *dvbapi_client;
263
264const char *boxdesc[] = { "none", "dreambox", "duckbox", "ufs910", "dbox2", "ipbox", "ipbox-pmt", "dm7000", "qboxhd", "coolstream", "neumo", "pc", "pc-nodmx", "samygo" };
265
266
267// when updating devices[BOX_COUNT] make sure to update these index defines
268#define BOX_INDEX_QBOXHD 0
269#define BOX_INDEX_DREAMBOX_DVBAPI3 1
270#define BOX_INDEX_COOLSTREAM 6
271
272static const struct box_devices devices[BOX_COUNT] =
273{
274 /* QboxHD (dvb-api-3)*/ { "/tmp/virtual_adapter/", "ca%d", "demux%d", "/tmp/camd.socket", DVBAPI_3 },
275 /* dreambox (dvb-api-3)*/ { "/dev/dvb/adapter%d/", "ca%d", "demux%d", "/tmp/camd.socket", DVBAPI_3 },
276 /* wetek (dvb-api-3)*/ { "/dev/dvb%d.", "ca%d", "demux%d", "/tmp/camd.socket", DVBAPI_3 },
277 /* dreambox (dvb-api-1)*/ { "/dev/dvb/card%d/", "ca%d", "demux%d", "/tmp/camd.socket", DVBAPI_1 },
278 /* neumo (dvb-api-1)*/ { "/dev/", "demuxapi", "demuxapi", "/tmp/camd.socket", DVBAPI_1 },
279#ifdef WITH_STAPI5
280 /* sh4 (stapi5)*/ { "/dev/stapi/", "stpti5_ioctl", "stpti5_ioctl", "/tmp/camd.socket", STAPI },
281#else
282 /* sh4 (stapi)*/ { "/dev/stapi/", "stpti4_ioctl", "stpti4_ioctl", "/tmp/camd.socket", STAPI },
283#endif
284 /* coolstream*/ { "/dev/cnxt/", "null", "null", "/tmp/camd.socket", COOLAPI },
285};
286
287static int32_t selected_box = -1;
288static int32_t selected_api = -1;
289static int32_t maxfilter = MAX_FILTER;
290static int32_t dir_fd = -1;
291static uint16_t last_client_proto_version = 0;
292static char* last_client_name = NULL;
293
294static int32_t ca_fd[MAX_DEMUX]; // holds fd handle of each ca device 0 = not in use
295static LLIST * ll_activestreampids; // list of all enabled streampids on ca devices
296
297static int32_t unassoc_fd[MAX_DEMUX];
298
299bool is_dvbapi_usr(char *usr) {
300 return streq(cfg.dvbapi_usr, usr);
301}
302
303struct s_emm_filter
304{
305 int32_t demux_id;
306 uchar filter[32];
307 uint16_t caid;
308 uint32_t provid;
309 uint16_t pid;
310 uint32_t num;
311 struct timeb time_started;
312};
313
314static LLIST *ll_emm_active_filter;
315static LLIST *ll_emm_inactive_filter;
316static LLIST *ll_emm_pending_filter;
317
318int32_t add_emmfilter_to_list(int32_t demux_id, uchar *filter, uint16_t caid, uint32_t provid, uint16_t emmpid, int32_t num, bool enable)
319{
320 if(!ll_emm_active_filter)
321 { ll_emm_active_filter = ll_create("ll_emm_active_filter"); }
322
323 if(!ll_emm_inactive_filter)
324 { ll_emm_inactive_filter = ll_create("ll_emm_inactive_filter"); }
325
326 if(!ll_emm_pending_filter)
327 { ll_emm_pending_filter = ll_create("ll_emm_pending_filter"); }
328
329 struct s_emm_filter *filter_item;
330 if(!cs_malloc(&filter_item, sizeof(struct s_emm_filter)))
331 { return 0; }
332
333 filter_item->demux_id = demux_id;
334 memcpy(filter_item->filter, filter, 32);
335 filter_item->caid = caid;
336 filter_item->provid = provid;
337 filter_item->pid = emmpid;
338 filter_item->num = num;
339 if (enable)
340 {
341 cs_ftime(&filter_item->time_started);
342 }
343 else
344 {
345 memset(&filter_item->time_started, 0, sizeof(filter_item->time_started));
346 }
347
348 if(num > 0)
349 {
350 ll_append(ll_emm_active_filter, filter_item);
351 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d added to active emmfilters (CAID %04X PROVID %06X EMMPID %04X)",
352 filter_item->demux_id, filter_item->num, filter_item->caid, filter_item->provid, filter_item->pid);
353 }
354 else if(num < 0)
355 {
356 ll_append(ll_emm_pending_filter, filter_item);
357 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter added to pending emmfilters (CAID %04X PROVID %06X EMMPID %04X)",
358 filter_item->demux_id, filter_item->caid, filter_item->provid, filter_item->pid);
359 }
360 else
361 {
362 ll_append(ll_emm_inactive_filter, filter_item);
363 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter added to inactive emmfilters (CAID %04X PROVID %06X EMMPID %04X)",
364 filter_item->demux_id, filter_item->caid, filter_item->provid, filter_item->pid);
365 }
366 return 1;
367}
368
369int32_t is_emmfilter_in_list_internal(LLIST *ll, uchar *filter, uint16_t emmpid, uint32_t provid, uint16_t caid)
370{
371 struct s_emm_filter *filter_item;
372 LL_ITER itr;
373 if(ll_count(ll) > 0)
374 {
375 itr = ll_iter_create(ll);
376 while((filter_item = ll_iter_next(&itr)) != NULL)
377 {
378 if(!memcmp(filter_item->filter, filter, 32) && (filter_item->pid == emmpid) && (filter_item->provid == provid) && (filter_item->caid == caid))
379 { return 1; }
380 }
381 }
382 return 0;
383}
384
385int32_t is_emmfilter_in_list(uchar *filter, uint16_t emmpid, uint32_t provid, uint16_t caid)
386{
387 if(!ll_emm_active_filter)
388 { ll_emm_active_filter = ll_create("ll_emm_active_filter"); }
389
390 if(!ll_emm_inactive_filter)
391 { ll_emm_inactive_filter = ll_create("ll_emm_inactive_filter"); }
392
393 if(!ll_emm_pending_filter)
394 { ll_emm_pending_filter = ll_create("ll_emm_pending_filter"); }
395
396 if(is_emmfilter_in_list_internal(ll_emm_active_filter, filter, emmpid, provid, caid))
397 { return 1; }
398 if(is_emmfilter_in_list_internal(ll_emm_inactive_filter, filter, emmpid, provid, caid))
399 { return 1; }
400 if(is_emmfilter_in_list_internal(ll_emm_pending_filter, filter, emmpid, provid, caid))
401 { return 1; }
402
403 return 0;
404}
405
406struct s_emm_filter *get_emmfilter_by_filternum_internal(LLIST *ll, int32_t demux_id, uint32_t num)
407{
408 struct s_emm_filter *filter;
409 LL_ITER itr;
410 if(ll_count(ll) > 0)
411 {
412 itr = ll_iter_create(ll);
413 while((filter = ll_iter_next(&itr)))
414 {
415 if(filter->demux_id == demux_id && filter->num == num)
416 { return filter; }
417 }
418 }
419 return NULL;
420}
421
422struct s_emm_filter *get_emmfilter_by_filternum(int32_t demux_id, uint32_t num)
423{
424 if(!ll_emm_active_filter)
425 { ll_emm_active_filter = ll_create("ll_emm_active_filter"); }
426
427 if(!ll_emm_inactive_filter)
428 { ll_emm_inactive_filter = ll_create("ll_emm_inactive_filter"); }
429
430 if(!ll_emm_pending_filter)
431 { ll_emm_pending_filter = ll_create("ll_emm_pending_filter"); }
432
433 struct s_emm_filter *emm_filter = NULL;
434 emm_filter = get_emmfilter_by_filternum_internal(ll_emm_active_filter, demux_id, num);
435 if(emm_filter)
436 { return emm_filter; }
437 emm_filter = get_emmfilter_by_filternum_internal(ll_emm_inactive_filter, demux_id, num);
438 if(emm_filter)
439 { return emm_filter; }
440 emm_filter = get_emmfilter_by_filternum_internal(ll_emm_pending_filter, demux_id, num);
441 if(emm_filter)
442 { return emm_filter; }
443
444 return NULL;
445}
446
447int8_t remove_emmfilter_from_list_internal(LLIST *ll, int32_t demux_id, uint16_t caid, uint32_t provid, uint16_t pid, uint32_t num)
448{
449 struct s_emm_filter *filter;
450 LL_ITER itr;
451 if(ll_count(ll) > 0)
452 {
453 itr = ll_iter_create(ll);
454 while((filter = ll_iter_next(&itr)))
455 {
456 if(filter->demux_id == demux_id && filter->caid == caid && filter->provid == provid && filter->pid == pid && filter->num == num)
457 {
458 ll_iter_remove_data(&itr);
459 return 1;
460 }
461 }
462 }
463 return 0;
464}
465
466void remove_emmfilter_from_list(int32_t demux_id, uint16_t caid, uint32_t provid, uint16_t pid, uint32_t num)
467{
468 if(ll_emm_active_filter && remove_emmfilter_from_list_internal(ll_emm_active_filter, demux_id, caid, provid, pid, num))
469 { return; }
470 if(ll_emm_inactive_filter && remove_emmfilter_from_list_internal(ll_emm_inactive_filter, demux_id, caid, provid, pid, num))
471 { return; }
472 if(ll_emm_pending_filter && remove_emmfilter_from_list_internal(ll_emm_pending_filter, demux_id, caid, provid, pid, num))
473 { return; }
474}
475
476void dvbapi_net_add_str(unsigned char *packet, int *size, const char *str)
477{
478 unsigned char *str_len = &packet[*size]; //string length
479 *size += 1;
480
481 *str_len = snprintf((char *) &packet[*size], DVBAPI_MAX_PACKET_SIZE - *size, "%s", str);
482 *size += *str_len;
483}
484
485int32_t dvbapi_net_send(uint32_t request, int32_t socket_fd, int32_t demux_index, uint32_t filter_number, unsigned char *data, struct s_client *client, ECM_REQUEST *er, uint16_t client_proto_version)
486{
487 unsigned char packet[DVBAPI_MAX_PACKET_SIZE]; //maximum possible packet size
488 int32_t size = 0;
489
490 // not connected?
491 if (socket_fd <= 0)
492 return 0;
493
494 // preparing packet - header
495 // in old protocol client expect this first byte as adapter index, changed in the new protocol
496 // to be always after request type (opcode)
497 if (client_proto_version <= 0)
498 packet[size++] = demux[demux_index].adapter_index; //adapter index - 1 byte
499
500 // type of request
501 uint32_t req = request;
502 if (client_proto_version >= 1)
503 req = htonl(req);
504 memcpy(&packet[size], &req, 4); //request - 4 bytes
505 size += 4;
506
507 // preparing packet - adapter index for proto >= 1
508 if ((request != DVBAPI_SERVER_INFO) && client_proto_version >= 1)
509 packet[size++] = demux[demux_index].adapter_index; //adapter index - 1 byte
510
511 // struct with data
512 switch (request)
513 {
514 case DVBAPI_SERVER_INFO:
515 {
516 int16_t proto_version = htons(DVBAPI_PROTOCOL_VERSION); //our protocol version
517 memcpy(&packet[size], &proto_version, 2);
518 size += 2;
519
520 unsigned char *info_len = &packet[size]; //info string length
521 size += 1;
522
523 *info_len = snprintf((char *) &packet[size], sizeof(packet) - size, "OSCam v%s, build r%s (%s)", CS_VERSION, CS_SVN_VERSION, CS_TARGET);
524 size += *info_len;
525 break;
526 }
527 case DVBAPI_ECM_INFO:
528 {
529 if (er->rc >= E_NOTFOUND)
530 return 0;
531
532 int8_t hops = 0;
533
534 uint16_t sid = htons(er->srvid); //service ID (program number)
535 memcpy(&packet[size], &sid, 2);
536 size += 2;
537
538 uint16_t caid = htons(er->caid); //CAID
539 memcpy(&packet[size], &caid, 2);
540 size += 2;
541
542 uint16_t pid = htons(er->pid); //PID
543 memcpy(&packet[size], &pid, 2);
544 size += 2;
545
546 uint32_t prid = htonl(er->prid); //Provider ID
547 memcpy(&packet[size], &prid, 4);
548 size += 4;
549
550 uint32_t ecmtime = htonl(client->cwlastresptime); //ECM time
551 memcpy(&packet[size], &ecmtime, 4);
552 size += 4;
553
554 dvbapi_net_add_str(packet, &size, get_cardsystem_desc_by_caid(er->caid)); //cardsystem name
555
556 switch (er->rc)
557 {
558 case E_FOUND:
559 if (er->selected_reader)
560 {
561 dvbapi_net_add_str(packet, &size, er->selected_reader->label); //reader
562 if (is_network_reader(er->selected_reader))
563 dvbapi_net_add_str(packet, &size, er->selected_reader->device); //from
564 else
565 dvbapi_net_add_str(packet, &size, "local"); //from
566 dvbapi_net_add_str(packet, &size, reader_get_type_desc(er->selected_reader, 1)); //protocol
567 hops = er->selected_reader->currenthops;
568 }
569 break;
570
571 case E_CACHE1:
572 dvbapi_net_add_str(packet, &size, "Cache"); //reader
573 dvbapi_net_add_str(packet, &size, "cache1"); //from
574 dvbapi_net_add_str(packet, &size, "none"); //protocol
575 break;
576
577 case E_CACHE2:
578 dvbapi_net_add_str(packet, &size, "Cache"); //reader
579 dvbapi_net_add_str(packet, &size, "cache2"); //from
580 dvbapi_net_add_str(packet, &size, "none"); //protocol
581 break;
582
583 case E_CACHEEX:
584 dvbapi_net_add_str(packet, &size, "Cache"); //reader
585 dvbapi_net_add_str(packet, &size, "cache3"); //from
586 dvbapi_net_add_str(packet, &size, "none"); //protocol
587 break;
588 }
589
590 packet[size++] = hops; //hops
591
592 break;
593 }
594 case DVBAPI_CA_SET_PID:
595 {
596 int sct_capid_size = sizeof(ca_pid_t);
597
598 if (client_proto_version >= 1)
599 {
600 ca_pid_t *capid = (ca_pid_t *) data;
601 capid->pid = htonl(capid->pid);
602 capid->index = htonl(capid->index);
603 }
604 memcpy(&packet[size], data, sct_capid_size);
605
606 size += sct_capid_size;
607 break;
608 }
609 case DVBAPI_CA_SET_DESCR:
610 {
611 int sct_cadescr_size = sizeof(ca_descr_t);
612
613 if (client_proto_version >= 1)
614 {
615 ca_descr_t *cadesc = (ca_descr_t *) data;
616 cadesc->index = htonl(cadesc->index);
617 cadesc->parity = htonl(cadesc->parity);
618 }
619 memcpy(&packet[size], data, sct_cadescr_size);
620
621 size += sct_cadescr_size;
622 break;
623 }
624 case DVBAPI_CA_SET_DESCR_MODE:
625 {
626 int sct_cadescr_mode_size = sizeof(ca_descr_mode_t);
627
628 if (client_proto_version >= 1)
629 {
630 ca_descr_mode_t *cadesc_mode = (ca_descr_mode_t *) data;
631 cadesc_mode->index = htonl(cadesc_mode->index);
632 cadesc_mode->algo = htonl(cadesc_mode->algo);
633 cadesc_mode->cipher_mode = htonl(cadesc_mode->cipher_mode);
634 }
635 memcpy(&packet[size], data, sct_cadescr_mode_size);
636
637 size += sct_cadescr_mode_size;
638 break;
639 }
640 case DVBAPI_DMX_SET_FILTER:
641 case DVBAPI_DMX_STOP:
642 {
643 int32_t sct_filter_size = sizeof(struct dmx_sct_filter_params);
644 packet[size++] = demux_index; //demux index - 1 byte
645 packet[size++] = filter_number; //filter number - 1 byte
646
647 if (data) // filter data when starting
648 {
649 if (client_proto_version >= 1)
650 {
651 struct dmx_sct_filter_params *fp = (struct dmx_sct_filter_params *) data;
652
653 // adding all dmx_sct_filter_params structure fields
654 // one by one to avoid padding problems
655 uint16_t pid = htons(fp->pid);
656 memcpy(&packet[size], &pid, 2);
657 size += 2;
658
659 memcpy(&packet[size], fp->filter.filter, 16);
660 size += 16;
661 memcpy(&packet[size], fp->filter.mask, 16);
662 size += 16;
663 memcpy(&packet[size], fp->filter.mode, 16);
664 size += 16;
665
666 uint32_t timeout = htonl(fp->timeout);
667 memcpy(&packet[size], &timeout, 4);
668 size += 4;
669
670 uint32_t flags = htonl(fp->flags);
671 memcpy(&packet[size], &flags, 4);
672 size += 4;
673 }
674 else
675 {
676 memcpy(&packet[size], data, sct_filter_size); //dmx_sct_filter_params struct
677 size += sct_filter_size;
678 }
679 }
680 else // pid when stopping
681 {
682 if (client_proto_version >= 1)
683 {
684 uint16_t pid = htons(demux[demux_index].demux_fd[filter_number].pid);
685 memcpy(&packet[size], &pid, 2);
686 size += 2;
687 }
688 else
689 {
690 uint16_t pid = demux[demux_index].demux_fd[filter_number].pid;
691 packet[size++] = pid >> 8;
692 packet[size++] = pid & 0xff;
693 }
694 }
695 break;
696 }
697 default: //unknown request
698 {
699 cs_log("ERROR: dvbapi_net_send: invalid request");
700 return 0;
701 }
702 }
703
704 // sending
705 cs_log_dump_dbg(D_DVBAPI, packet, size, "Sending packet to dvbapi client (fd=%d):", socket_fd);
706 send(socket_fd, &packet, size, MSG_DONTWAIT);
707
708 // always returning success as the client could close socket
709 return 0;
710}
711
712int32_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 type,
713 int8_t add_to_emm_list)
714{
715 int32_t ret = -1, n = -1, i, filterfd = -1;
716
717 for(i = 0; i < maxfilter && demux[demux_id].demux_fd[i].fd > 0; i++) { ; }
718
719 if(i >= maxfilter)
720 {
721 cs_log_dbg(D_DVBAPI, "no free filter");
722 return -1;
723 }
724 n = i;
725
726 if(USE_OPENXCAS)
727 {
728 if(type == TYPE_ECM)
729 {
730 openxcas_set_caid(demux[demux_id].ECMpids[pidindex].CAID);
731 openxcas_set_ecm_pid(pid);
732 }
733 demux[demux_id].demux_fd[n].fd = DUMMY_FD;
734 demux[demux_id].demux_fd[n].pidindex = pidindex;
735 demux[demux_id].demux_fd[n].pid = pid;
736 demux[demux_id].demux_fd[n].caid = caid;
737 demux[demux_id].demux_fd[n].provid = provid;
738 demux[demux_id].demux_fd[n].type = type;
739 memcpy(demux[demux_id].demux_fd[n].filter, filt, 16); // copy filter to check later on if receiver delivered accordingly
740 memcpy(demux[demux_id].demux_fd[n].mask, mask, 16); // copy mask to check later on if receiver delivered accordingly
741 return 1;
742 }
743
744 switch(api)
745 {
746 case DVBAPI_3:
747 if (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
748 ret = filterfd = DUMMY_FD;
749 else
750 ret = filterfd = dvbapi_open_device(0, demux[demux_id].demux_index, demux[demux_id].adapter_index);
751 if(ret < 0) { return ret; } // return if device cant be opened!
752 struct dmx_sct_filter_params sFP2;
753
754 memset(&sFP2, 0, sizeof(sFP2));
755
756 sFP2.pid = pid;
757 sFP2.timeout = timeout;
758 sFP2.flags = DMX_IMMEDIATE_START;
759 if(cfg.dvbapi_boxtype == BOXTYPE_NEUMO)
760 {
761 //DeepThought: on dgs/cubestation and neumo images, perhaps others
762 //the following code is needed to descramble
763 sFP2.filter.filter[0] = filt[0];
764 sFP2.filter.mask[0] = mask[0];
765 sFP2.filter.filter[1] = 0;
766 sFP2.filter.mask[1] = 0;
767 sFP2.filter.filter[2] = 0;
768 sFP2.filter.mask[2] = 0;
769 memcpy(sFP2.filter.filter + 3, filt + 1, 16 - 3);
770 memcpy(sFP2.filter.mask + 3, mask + 1, 16 - 3);
771 //DeepThought: in the drivers of the dgs/cubestation and neumo images,
772 //dvbapi 1 and 3 are somehow mixed. In the kernel drivers, the DMX_SET_FILTER
773 //ioctl expects to receive a dmx_sct_filter_params structure (DVBAPI 3) but
774 //due to a bug its sets the "positive mask" wrongly (they should be all 0).
775 //On the other hand, the DMX_SET_FILTER1 ioctl also uses the dmx_sct_filter_params
776 //structure, which is incorrect (it should be dmxSctFilterParams).
777 //The only way to get it right is to call DMX_SET_FILTER1 with the argument
778 //expected by DMX_SET_FILTER. Otherwise, the timeout parameter is not passed correctly.
779 ret = dvbapi_ioctl(filterfd, DMX_SET_FILTER1, &sFP2);
780 }
781 else
782 {
783 memcpy(sFP2.filter.filter, filt, 16);
784 memcpy(sFP2.filter.mask, mask, 16);
785 if (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
786 ret = dvbapi_net_send(DVBAPI_DMX_SET_FILTER, demux[demux_id].socket_fd, demux_id, n, (unsigned char *) &sFP2, NULL, NULL, demux[demux_id].client_proto_version);
787 else
788 ret = dvbapi_ioctl(filterfd, DMX_SET_FILTER, &sFP2);
789 }
790 break;
791
792 case DVBAPI_1:
793 ret = filterfd = dvbapi_open_device(0, demux[demux_id].demux_index, demux[demux_id].adapter_index);
794 if(ret < 0) { return ret; } // return if device cant be opened!
795 struct dmxSctFilterParams sFP1;
796
797 memset(&sFP1, 0, sizeof(sFP1));
798
799 sFP1.pid = pid;
800 sFP1.timeout = timeout;
801 sFP1.flags = DMX_IMMEDIATE_START;
802 memcpy(sFP1.filter.filter, filt, 16);
803 memcpy(sFP1.filter.mask, mask, 16);
804 ret = dvbapi_ioctl(filterfd, DMX_SET_FILTER1, &sFP1);
805
806 break;
807#if defined(WITH_STAPI) || defined(WITH_STAPI5)
808 case STAPI:
809 ret = filterfd = stapi_set_filter(demux_id, pid, filt, mask, n, demux[demux_id].pmt_file);
810 if(ret <= 0)
811 {
812 ret = -1; // error setting filter!
813 }
814 break;
815#endif
816#if defined WITH_COOLAPI || defined WITH_COOLAPI2
817 case COOLAPI:
818 ret = filterfd = coolapi_open_device(demux[demux_id].demux_index, demux_id);
819 if(ret > 0)
820 {
821 ret = coolapi_set_filter(filterfd, n, pid, filt, mask, type);
822 }
823 else
824 {
825 ret = -1; // fail
826 }
827 break;
828#endif
829 default:
830 break;
831 }
832 if(ret != -1) // filter set successful
833 {
834 // only register if filter was set successful
835 demux[demux_id].demux_fd[n].fd = filterfd;
836 demux[demux_id].demux_fd[n].pidindex = pidindex;
837 demux[demux_id].demux_fd[n].pid = pid;
838 demux[demux_id].demux_fd[n].caid = caid;
839 demux[demux_id].demux_fd[n].provid = provid;
840 demux[demux_id].demux_fd[n].type = type;
841 memcpy(demux[demux_id].demux_fd[n].filter, filt, 16); // copy filter to check later on if receiver delivered accordingly
842 memcpy(demux[demux_id].demux_fd[n].mask, mask, 16); // copy mask to check later on if receiver delivered accordingly
843 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d started successfully (caid %04X provid %06X pid %04X)", demux_id, n + 1, caid, provid, pid);
844 if(type == TYPE_EMM && add_to_emm_list){
845 add_emmfilter_to_list(demux_id, filt, caid, provid, pid, n + 1, true);
846 }
847 }
848 else
849 {
850 cs_log("ERROR: Could not start demux filter (api: %d errno=%d %s)", selected_api, errno, strerror(errno));
851 }
852
853 return ret;
854}
855
856static int32_t dvbapi_detect_api(void)
857{
858#if defined WITH_COOLAPI || defined WITH_COOLAPI2
859 selected_api = COOLAPI;
860 selected_box = BOX_INDEX_COOLSTREAM;
861 disable_pmt_files = 1;
862 cfg.dvbapi_listenport = 0;
863 cs_log("Detected Coolstream API");
864 return 1;
865#else
866 if (cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX || cfg.dvbapi_boxtype == BOXTYPE_PC ) {
867 selected_api = DVBAPI_3;
868 selected_box = BOX_INDEX_DREAMBOX_DVBAPI3;
869 if (cfg.dvbapi_listenport)
870 {
871 cs_log("Using TCP listen socket, API forced to DVBAPIv3 (%d), userconfig boxtype: %d", selected_api, cfg.dvbapi_boxtype);
872 }
873 else
874 {
875 cs_log("Using %s listen socket, API forced to DVBAPIv3 (%d), userconfig boxtype: %d", devices[selected_box].cam_socket_path, selected_api, cfg.dvbapi_boxtype);
876 }
877 return 1;
878 }
879 else if(cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
880 {
881 selected_api = DVBAPI_3;
882 selected_box = BOX_INDEX_QBOXHD;
883 cfg.dvbapi_listenport = 0;
884 disable_pmt_files = 1;
885 cs_log("Using SamyGO dvbapi v0.1");
886 return 1;
887 }
888 else
889 {
890 cfg.dvbapi_listenport = 0;
891 }
892
893 int32_t i = 0, n = 0, devnum = -1, dmx_fd = 0, filtercount = 0;
894 char device_path[128], device_path2[128];
895 static LLIST *ll_max_fd;
896 ll_max_fd = ll_create("ll_max_fd");
897 LL_ITER itr;
898
899 struct s_open_fd
900 {
901 uint32_t fd;
902 };
903
904 struct s_open_fd *open_fd;
905
906 while (i < BOX_COUNT)
907 {
908 do
909 {
910 snprintf(device_path2, sizeof(device_path2), devices[i].demux_device, 0);
911 snprintf(device_path, sizeof(device_path), devices[i].path, n);
912 strncat(device_path, device_path2, sizeof(device_path) - strlen(device_path) - 1);
913 filtercount = 0;
914 while((dmx_fd = open(device_path, O_RDWR | O_NONBLOCK)) > 0 && filtercount < MAX_FILTER)
915 {
916 filtercount++;
917 if(!cs_malloc(&open_fd, sizeof(struct s_open_fd)))
918 {
919 close(dmx_fd);
920 break;
921 }
922 open_fd->fd = dmx_fd;
923 ll_append(ll_max_fd, open_fd);
924 }
925
926 if(filtercount > 0)
927 {
928 itr = ll_iter_create(ll_max_fd);
929 while((open_fd = ll_iter_next(&itr)))
930 {
931 dmx_fd = open_fd->fd;
932 do
933 {
934 ;
935 }
936 while(close(dmx_fd)<0);
937 ll_iter_remove_data(&itr);
938 }
939 devnum = i;
940 selected_api = devices[devnum].api;
941 selected_box = devnum;
942 if(cfg.dvbapi_boxtype == BOXTYPE_NEUMO)
943 {
944 selected_api = DVBAPI_3; //DeepThought
945 }
946#if defined(WITH_STAPI) || defined(WITH_STAPI5)
947 if(selected_api == STAPI && stapi_open() == 0)
948 {
949 cs_log("ERROR: stapi: setting up stapi failed.");
950 return 0;
951 }
952#endif
953 maxfilter = filtercount;
954 cs_log("Detected %s Api: %d, userconfig boxtype: %d maximum amount of possible filters is %d (oscam limit is %d)",
955 device_path, selected_api, cfg.dvbapi_boxtype, filtercount, MAX_FILTER);
956 }
957
958 /* try at least 8 adapters */
959 if ((strchr(devices[i].path, '%') != NULL) && (n < 8)) n++; else { n = 0; i++; }
960 }while(n != 0); // n is set to 0 again if 8 adapters are tried!
961
962 if(devnum != -1) break; // check if box detected
963 }
964
965 ll_destroy(&ll_max_fd);
966
967 if(devnum == -1) { return 0; }
968
969#endif
970 return 1;
971}
972
973static int32_t dvbapi_read_device(int32_t dmx_fd, unsigned char *buf, uint32_t length)
974{
975 int32_t readed;
976 uint32_t count = 0;
977 struct pollfd pfd[1];
978
979 pfd[0].fd = dmx_fd;
980 pfd[0].events = (POLLIN | POLLPRI);
981
982 while (count < length )
983 {
984 if (poll(pfd,1,0)) // fd ready for reading?
985 {
986 if (pfd[0].revents & (POLLIN | POLLPRI)) // is there data to read?
987 {
988 readed = read(dmx_fd, &buf[count], length-count);
989 if(readed < 0) // error occured while reading
990 {
991 if(errno == EINTR || errno == EAGAIN) { continue; } // try again in case of interrupt
992 cs_log("ERROR: Read error on fd %d (errno=%d %s)", dmx_fd, errno, strerror(errno));
993 return (errno == EOVERFLOW ? 0 : -1);
994 }
995 if(readed > 0) // succesfull read
996 {
997 count += readed;
998 }
999 if(readed == 0 && count > 0) // nothing to read left
1000 {
1001 break;
1002 }
1003 }
1004 else return -1; // other events than pollin/pri means bad news -> abort!
1005 }
1006 else break;
1007 }
1008 cs_log_dump_dbg(D_TRACE, buf, count, "Received:");
1009 return count;
1010}
1011
1012int32_t dvbapi_open_device(int32_t type, int32_t num, int32_t adapter)
1013{
1014 int32_t dmx_fd, ret;
1015 int32_t ca_offset = 0;
1016 char device_path[128], device_path2[128];
1017
1018 if(cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
1019 return DUMMY_FD;
1020
1021 if(type == 0)
1022 {
1023 snprintf(device_path2, sizeof(device_path2), devices[selected_box].demux_device, num);
1024 snprintf(device_path, sizeof(device_path), devices[selected_box].path, adapter);
1025
1026 strncat(device_path, device_path2, sizeof(device_path) - strlen(device_path) - 1);
1027 }
1028 else
1029 {
1030 if(cfg.dvbapi_boxtype == BOXTYPE_DUCKBOX || cfg.dvbapi_boxtype == BOXTYPE_DBOX2 || cfg.dvbapi_boxtype == BOXTYPE_UFS910)
1031 { ca_offset = 1; }
1032
1033 if(cfg.dvbapi_boxtype == BOXTYPE_QBOXHD)
1034 { num = 0; }
1035
1036 if(cfg.dvbapi_boxtype == BOXTYPE_PC)
1037 { num = 0; }
1038
1039 if(cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
1040 { num = 0; }
1041
1042 snprintf(device_path2, sizeof(device_path2), devices[selected_box].ca_device, num + ca_offset);
1043 snprintf(device_path, sizeof(device_path), devices[selected_box].path, adapter);
1044
1045 strncat(device_path, device_path2, sizeof(device_path) - strlen(device_path) - 1);
1046 }
1047
1048 if (cfg.dvbapi_boxtype == BOXTYPE_SAMYGO) {
1049
1050 if(type == 0)
1051 {
1052 struct sockaddr_un saddr;
1053 memset(&saddr, 0, sizeof(saddr));
1054 saddr.sun_family = AF_UNIX;
1055 strncpy(saddr.sun_path, device_path, sizeof(saddr.sun_path) - 1);
1056 dmx_fd = socket(AF_UNIX, SOCK_STREAM, 0);
1057 ret = connect(dmx_fd, (struct sockaddr *)&saddr, sizeof(saddr));
1058 if (ret < 0)
1059 { close(dmx_fd); }
1060 }
1061 else if(type == 1)
1062 {
1063 int32_t udp_port = 9000;
1064 struct sockaddr_in saddr;
1065 memset(&saddr, 0, sizeof(saddr));
1066 saddr.sin_family = AF_INET;
1067 saddr.sin_port = htons(udp_port + adapter);
1068 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
1069 dmx_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
1070 set_nonblock(dmx_fd, true);
1071 ret = connect(dmx_fd, (struct sockaddr *) &saddr, sizeof(saddr));
1072 if(ret < 0)
1073 { close(dmx_fd); }
1074 cs_log_dbg(D_DVBAPI, "NET DEVICE open (port = %d) fd %d", udp_port + adapter, dmx_fd);
1075 }
1076 else
1077 {
1078 ret = -1;
1079 }
1080 } else {
1081 dmx_fd = ret = open(device_path, O_RDWR | O_NONBLOCK);
1082 }
1083
1084 if(ret < 0)
1085 {
1086 cs_log("ERROR: Can't open device %s (errno=%d %s)", device_path, errno, strerror(errno));
1087 return -1;
1088 }
1089
1090 cs_log_dbg(D_DVBAPI, "Open device %s (fd %d)", device_path, dmx_fd);
1091
1092 return dmx_fd;
1093}
1094
1095uint16_t tunemm_caid_map(uint8_t direct, uint16_t caid, uint16_t srvid)
1096{
1097 int32_t i;
1098 struct s_client *cl = cur_client();
1099 TUNTAB *ttab = &cl->ttab;
1100
1101 if (!ttab->ttnum)
1102 return caid;
1103
1104 if(direct)
1105 {
1106 for(i = 0; i < ttab->ttnum; i++)
1107 {
1108 if(caid == ttab->ttdata[i].bt_caidto
1109 && (srvid == ttab->ttdata[i].bt_srvid || ttab->ttdata[i].bt_srvid == 0xFFFF || !ttab->ttdata[i].bt_srvid))
1110 { return ttab->ttdata[i].bt_caidfrom; }
1111 }
1112 }
1113 else
1114 {
1115 for(i = 0; i < ttab->ttnum; i++)
1116 {
1117 if(caid == ttab->ttdata[i].bt_caidfrom
1118 && (srvid == ttab->ttdata[i].bt_srvid || ttab->ttdata[i].bt_srvid == 0xFFFF || !ttab->ttdata[i].bt_srvid))
1119 { return ttab->ttdata[i].bt_caidto; }
1120 }
1121 }
1122 return caid;
1123}
1124
1125int32_t dvbapi_stop_filter(int32_t demux_index, int32_t type)
1126{
1127 int32_t g, error = 0;
1128
1129 for(g = 0; g < MAX_FILTER; g++) // just stop them all, we dont want to risk leaving any stale filters running due to lowering of maxfilters
1130 {
1131 if(demux[demux_index].demux_fd[g].type == type)
1132 {
1133 if(dvbapi_stop_filternum(demux_index, g) == -1)
1134 {
1135 error = 1;
1136 }
1137 }
1138 }
1139 return !error; // on error return 0, all ok 1
1140}
1141
1142int32_t dvbapi_stop_filternum(int32_t demux_index, int32_t num)
1143{
1144 int32_t retfilter = -1, retfd = -1, fd = demux[demux_index].demux_fd[num].fd, try = 0;
1145 if(USE_OPENXCAS)
1146 {
1147 demux[demux_index].demux_fd[num].type = 0;
1148 demux[demux_index].demux_fd[num].fd = 0;
1149 return 1; // all ok!
1150 }
1151
1152 if(fd > 0)
1153 {
1154 do
1155 {
1156 errno = 0;
1157 if(try)
1158 {
1159 cs_sleepms(50);
1160 }
1161 try++;
1162 cs_log_dbg(D_DVBAPI, "Demuxer %d stop filter %d try %d (fd: %d api: %d, caid: %04X, provid: %06X, %spid: %04X)", demux_index, num + 1, try,
1163 fd, selected_api, demux[demux_index].demux_fd[num].caid, demux[demux_index].demux_fd[num].provid,
1164 (demux[demux_index].demux_fd[num].type == TYPE_ECM ? "ecm" : "emm"), demux[demux_index].demux_fd[num].pid);
1165
1166 switch(selected_api)
1167 {
1168 case DVBAPI_3:
1169 if (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
1170 retfilter = dvbapi_net_send(DVBAPI_DMX_STOP, demux[demux_index].socket_fd, demux_index, num, NULL, NULL, NULL, demux[demux_index].client_proto_version);
1171 else
1172 retfilter = dvbapi_ioctl(fd, DMX_STOP, NULL);
1173 break;
1174
1175 case DVBAPI_1:
1176 retfilter = dvbapi_ioctl(fd, DMX_STOP, NULL);
1177 break;
1178
1179#if defined(WITH_STAPI) || defined(WITH_STAPI5)
1180 case STAPI:
1181 retfilter = stapi_remove_filter(demux_index, num, demux[demux_index].pmt_file);
1182 if(retfilter != 1) // stapi returns 0 for error, 1 for all ok
1183 {
1184 retfilter = -1;
1185 }
1186 break;
1187#endif
1188#if defined WITH_COOLAPI || defined WITH_COOLAPI2
1189 case COOLAPI:
1190 retfilter = coolapi_remove_filter(fd, num);
1191 if(retfilter >=0 )
1192 {
1193 retfd = coolapi_close_device(fd);
1194 }
1195 break;
1196#endif
1197 default:
1198 break;
1199 }
1200 if(errno == 9) {retfilter = 0;} // no error on bad file descriptor
1201 } while (retfilter < 0 && try < 10);
1202
1203#if !defined WITH_COOLAPI && !defined WITH_COOLAPI2 // no fd close for coolapi and stapi, all others do close fd!
1204 try = 0;
1205 do
1206 {
1207 if(try)
1208 {
1209 errno = 0;
1210 cs_sleepms(50);
1211 }
1212 try++;
1213 if (!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX && errno != 9) //on bad filterfd dont try to close!
1214 {
1215 if(selected_api == STAPI)
1216 {
1217 retfd = 0; // stapi closes its own filter fd!
1218 }
1219 else
1220 {
1221 flush_read_fd(demux_index, num, fd); // flush filter input buffer in attempt to avoid overflow receivers internal buffer
1222 retfd = close(fd);
1223 if(errno == 9) { retfd = 0; } // no error on bad file descriptor
1224 }
1225 }
1226 else
1227 retfd = 0;
1228
1229 } while (retfd < 0 && try < 10);
1230#endif
1231 }
1232 else // fd <=0
1233 {
1234 return 1; // filter was already killed!
1235 }
1236
1237 if(retfilter < 0) // error on remove filter
1238 {
1239 cs_log("ERROR: Demuxer %d could not stop Filter %d (fd:%d api:%d errno=%d %s)", demux_index, num + 1, fd, selected_api, errno, strerror(errno));
1240 return retfilter;
1241 }
1242
1243 if(retfd < 0) // error on close filter fd
1244 {
1245 cs_log("ERROR: Demuxer %d could not close fd of Filter %d (fd=%d api:%d errno=%d %s)", demux_index, num + 1, fd,
1246 selected_api, errno, strerror(errno));
1247 return retfd;
1248 }
1249
1250 // code below runs only if nothing has gone wrong
1251
1252 if(demux[demux_index].demux_fd[num].type == TYPE_ECM) //ecm filter stopped: reset index!
1253 {
1254 int32_t oldpid = demux[demux_index].demux_fd[num].pidindex;
1255 int32_t curpid = demux[demux_index].pidindex;
1256
1257 // workaround: below dont run on stapi since it handles it own pids.... stapi need to be better integrated in oscam dvbapi.
1258 if(selected_api != STAPI)
1259 {
1260 int32_t z;
1261 for(z = 0; z < MAX_STREAM_INDICES; z++)
1262 {
1263 ca_index_t idx = demux[demux_index].ECMpids[oldpid].index[z];
1264 demux[demux_index].ECMpids[oldpid].index[z] = INDEX_INVALID;
1265
1266 if(idx != INDEX_INVALID) // if in use
1267 {
1268 int32_t i;
1269 for(i = 0; i < demux[demux_index].STREAMpidcount; i++)
1270 {
1271 int8_t match = 0;
1272 // check streams of old disabled ecmpid
1273 if(!demux[demux_index].ECMpids[oldpid].streams || ((demux[demux_index].ECMpids[oldpid].streams & (1 << i)) == (uint) (1 << i)))
1274 {
1275 // check if new ecmpid is using same streams
1276 if(curpid != -1 && (!demux[demux_index].ECMpids[curpid].streams || ((demux[demux_index].ECMpids[curpid].streams & (1 << i)) == (uint) (1 << i))))
1277 {
1278 continue; // found same stream on old and new ecmpid -> skip! (and leave it enabled!)
1279 }
1280
1281 int32_t pidtobestopped = demux[demux_index].STREAMpids[i];
1282 int32_t j, k, otherdemuxpid;
1283 ca_index_t otherdemuxidx;
1284
1285 for(j = 0; j < MAX_DEMUX; j++) // check other demuxers for same streampid with same index
1286 {
1287 if(demux[j].program_number == 0) { continue; } // skip empty demuxers
1288 if(demux_index == j) { continue; } // skip same demuxer
1289 if(demux[j].ca_mask != demux[demux_index].ca_mask) { continue;} // skip streampid running on other ca device
1290
1291 otherdemuxpid = demux[j].pidindex;
1292 if(otherdemuxpid == -1) { continue; } // Other demuxer not descrambling yet
1293
1294 int32_t y;
1295 for(y = 0; y < MAX_STREAM_INDICES; y++)
1296 {
1297 otherdemuxidx = demux[j].ECMpids[otherdemuxpid].index[y];
1298 if(otherdemuxidx == INDEX_INVALID || otherdemuxidx != idx) { continue; } // Other demuxer has no index yet, or index is different
1299
1300 for(k = 0; k < demux[j].STREAMpidcount; k++)
1301 {
1302 if(!demux[j].ECMpids[otherdemuxpid].streams || ((demux[j].ECMpids[otherdemuxpid].streams & (1 << k)) == (uint) (1 << k)))
1303 {
1304 if(demux[j].STREAMpids[k] == pidtobestopped)
1305 {
1306 continue; // found same streampid enabled with same index on one or more other demuxers -> skip! (and leave it enabled!)
1307 }
1308 }
1309 match = 1; // matching stream found
1310 }
1311 }
1312 }
1313
1314 if(!match)
1315 {
1316 for(j = 0; j < MAX_DEMUX; j++)
1317 {
1318 if(((demux[demux_index].ca_mask & (1 << j)) == (uint32_t) (1 << j)))
1319 {
1320 remove_streampid_from_list(j, pidtobestopped, idx);
1321 break;
1322 }
1323 }
1324 }
1325 }
1326 }
1327 }
1328 }
1329 }
1330 }
1331
1332 if(demux[demux_index].demux_fd[num].type == TYPE_EMM) // If emm type remove from emm filterlist
1333 {
1334 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 + 1);
1335 }
1336 demux[demux_index].demux_fd[num].type = 0;
1337 demux[demux_index].demux_fd[num].fd = 0;
1338 return 1; // all ok!
1339}
1340
1341void dvbapi_start_filter(int32_t demux_id, int32_t pidindex, uint16_t pid, uint16_t caid, uint32_t provid, uchar table, uchar mask, int32_t timeout, int32_t type)
1342{
1343 int32_t o;
1344 for(o = 0; o < maxfilter; o++) // check if filter is present
1345 {
1346 if(demux[demux_id].demux_fd[o].fd > 0 &&
1347 demux[demux_id].demux_fd[o].pid == pid &&
1348 demux[demux_id].demux_fd[o].type == type &&
1349 demux[demux_id].demux_fd[o].filter[0] == table &&
1350 demux[demux_id].demux_fd[o].mask[0] == mask
1351 )
1352 {
1353 return;
1354 }
1355 }
1356 uchar filter[32];
1357 memset(filter, 0, 32);
1358
1359 filter[0] = table;
1360 filter[16] = mask;
1361
1362 cs_log_dbg(D_DVBAPI, "Demuxer %d try to start new filter for caid: %04X, provid: %06X, pid: %04X", demux_id, caid, provid, pid);
1363 dvbapi_set_filter(demux_id, selected_api, pid, caid, provid, filter, filter + 16, timeout, pidindex, type, 0);
1364}
1365
1366void dvbapi_start_sdt_filter(int32_t demux_index)
1367{
1368 dvbapi_start_filter(demux_index, demux[demux_index].pidindex, 0x11, 0x001, 0x01, 0x42, 0xFF, 0, TYPE_SDT);
1369 demux[demux_index].sdt_filter = 0;
1370}
1371
1372void dvbapi_start_pat_filter(int32_t demux_index)
1373{
1374 dvbapi_start_filter(demux_index, demux[demux_index].pidindex, 0x00, 0x001, 0x01, 0x00, 0xFF, 0, TYPE_PAT);
1375}
1376
1377void dvbapi_start_pmt_filter(int32_t demux_index, int32_t pmt_pid)
1378{
1379 uchar filter[16], mask[16];
1380 memset(filter, 0, 16);
1381 memset(mask, 0, 16);
1382
1383 filter[0] = 0x02;
1384 i2b_buf(2, demux[demux_index].program_number, filter + 1); // add srvid to filter since the pid can deliver pmt for multiple srvid
1385 mask[0] = 0xFF;
1386 mask[1] = 0xFF;
1387 mask[2] = 0xFF;
1388 dvbapi_set_filter(demux_index, selected_api, pmt_pid, 0x001, 0x01, filter, mask, 0, 0, TYPE_PMT, 0);
1389}
1390
1391void dvbapi_start_emm_filter(int32_t demux_index)
1392{
1393 unsigned int j;
1394 if(!demux[demux_index].EMMpidcount)
1395 { return; }
1396
1397 //if (demux[demux_index].emm_filter)
1398 // return;
1399
1400
1401 struct s_csystem_emm_filter *dmx_filter = NULL;
1402 unsigned int filter_count = 0;
1403 uint16_t caid, ncaid;
1404 uint32_t provid;
1405
1406 struct s_reader *rdr = NULL;
1407 struct s_client *cl = cur_client();
1408 if(!cl || !cl->aureader_list)
1409 { return; }
1410
1411 LL_ITER itr = ll_iter_create(cl->aureader_list);
1412 while((rdr = ll_iter_next(&itr)))
1413 {
1414 if(!(rdr->grp & cl->grp))
1415 { continue; }
1416 if(rdr->audisabled || !rdr->enable || (!is_network_reader(rdr) && rdr->card_status != CARD_INSERTED))
1417 { continue; }
1418
1419 const struct s_cardsystem *csystem;
1420 uint16_t c, match;
1421 cs_log_dbg(D_DVBAPI, "Demuxer %d matching reader %s against available emmpids -> START!", demux_index, rdr->label);
1422 for(c = 0; c < demux[demux_index].EMMpidcount; c++)
1423 {
1424 caid = ncaid = demux[demux_index].EMMpids[c].CAID;
1425 if(!caid) continue;
1426
1427 if(chk_is_betatunnel_caid(caid) == 2)
1428 {
1429 ncaid = tunemm_caid_map(FROM_TO, caid, demux[demux_index].program_number);
1430 }
1431 provid = demux[demux_index].EMMpids[c].PROVID;
1432 if (caid == ncaid)
1433 {
1434 match = emm_reader_match(rdr, caid, provid);
1435 }
1436 else
1437 {
1438 match = emm_reader_match(rdr, ncaid, provid);
1439 }
1440 if(match)
1441 {
1442 csystem = get_cardsystem_by_caid(caid);
1443 if(csystem)
1444 {
1445 if(caid != ncaid)
1446 {
1447 csystem = get_cardsystem_by_caid(ncaid);
1448 if(csystem && csystem->get_tunemm_filter)
1449 {
1450 csystem->get_tunemm_filter(rdr, &dmx_filter, &filter_count);
1451 cs_log_dbg(D_DVBAPI, "Demuxer %d setting emm filter for betatunnel: %04X -> %04X", demux_index, ncaid, caid);
1452 }
1453 else
1454 {
1455 cs_log_dbg(D_DVBAPI, "Demuxer %d cardsystem for emm filter for caid %04X of reader %s not found", demux_index, ncaid, rdr->label);
1456 continue;
1457 }
1458 }
1459 else if (csystem->get_emm_filter)
1460 {
1461 csystem->get_emm_filter(rdr, &dmx_filter, &filter_count);
1462 }
1463 }
1464 else
1465 {
1466 cs_log_dbg(D_DVBAPI, "Demuxer %d cardsystem for emm filter for caid %04X of reader %s not found", demux_index, caid, rdr->label);
1467 continue;
1468 }
1469
1470 for(j = 0; j < filter_count ; j++)
1471 {
1472 if(dmx_filter[j].enabled == 0)
1473 { continue; }
1474
1475 uchar filter[32];
1476 memset(filter, 0, sizeof(filter)); // reset filter
1477 uint32_t usefilterbytes = 16; // default use all filters
1478 memcpy(filter, dmx_filter[j].filter, usefilterbytes);
1479 memcpy(filter + 16, dmx_filter[j].mask, usefilterbytes);
1480 int32_t emmtype = dmx_filter[j].type;
1481
1482 if(filter[0] && (((1 << (filter[0] % 0x80)) & rdr->b_nano) && !((1 << (filter[0] % 0x80)) & rdr->s_nano)))
1483 {
1484 cs_log_dbg(D_DVBAPI, "Demuxer %d reader %s emmfilter %d/%d blocked by userconfig -> SKIP!", demux_index, rdr->label, j+1, filter_count);
1485 continue;
1486 }
1487
1488 if((rdr->blockemm & emmtype) && !(((1 << (filter[0] % 0x80)) & rdr->s_nano) || (rdr->saveemm & emmtype)))
1489 {
1490 cs_log_dbg(D_DVBAPI, "Demuxer %d reader %s emmfilter %d/%d blocked by userconfig -> SKIP!", demux_index, rdr->label, j+1, filter_count);
1491 continue;
1492 }
1493
1494 if(demux[demux_index].EMMpids[c].type & emmtype)
1495 {
1496 cs_log_dbg(D_DVBAPI, "Demuxer %d reader %s emmfilter %d/%d type match -> ENABLE!", demux_index, rdr->label, j+1, filter_count);
1497 check_add_emmpid(demux_index, filter, c, emmtype);
1498 }
1499 else
1500 {
1501 cs_log_dbg(D_DVBAPI, "Demuxer %d reader %s emmfilter %d/%d type mismatch -> SKIP!", demux_index, rdr->label, j+1, filter_count);
1502 }
1503 }
1504
1505 // dmx_filter not use below this point;
1506 NULLFREE(dmx_filter);
1507 filter_count = 0;
1508 }
1509 }
1510 cs_log_dbg(D_DVBAPI, "Demuxer %d matching reader %s against available emmpids -> DONE!", demux_index, rdr->label);
1511 }
1512 if(demux[demux_index].emm_filter == -1) // first run -1
1513 {
1514 demux[demux_index].emm_filter = 0;
1515 }
1516 cs_log_dbg(D_DVBAPI, "Demuxer %d handles %i emm filters", demux_index, demux[demux_index].emm_filter);
1517}
1518
1519void dvbapi_add_ecmpid_int(int32_t demux_id, uint16_t caid, uint16_t ecmpid, uint32_t provid, char *txt)
1520{
1521 int32_t n, added = 0;
1522
1523 if(demux[demux_id].ECMpidcount >= ECM_PIDS)
1524 { return; }
1525
1526 int32_t stream = demux[demux_id].STREAMpidcount - 1;
1527 for(n = 0; n < demux[demux_id].ECMpidcount; n++)
1528 {
1529 if(demux[demux_id].ECMpids[n].CAID == caid && demux[demux_id].ECMpids[n].ECM_PID == ecmpid && (!provid || (provid && demux[demux_id].ECMpids[n].PROVID == provid)))
1530 {
1531 added = 1;
1532 if(stream >-1)
1533 {
1534 if(!demux[demux_id].ECMpids[n].streams)
1535 {
1536 //we already got this caid/ecmpid as global, no need to add the single stream
1537 cs_log_dbg(D_DVBAPI, "Demuxer %d skipped stream CAID: %04X ECM_PID: %04X PROVID: %06X (Same as ECMPID %d)", demux_id, caid, ecmpid, provid, n);
1538 continue;
1539 }
1540 demux[demux_id].ECMpids[n].streams |= (1 << stream);
1541 cs_log("Demuxer %d added stream to ecmpid %d CAID: %04X ECM_PID: %04X PROVID: %06X", demux_id, n, caid, ecmpid, provid);
1542 }
1543 }
1544 }
1545
1546 if(added == 1)
1547 { return; }
1548 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].ECM_PID = ecmpid;
1549 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CAID = caid;
1550 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].PROVID = provid;
1551 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CHID = 0x10000; // reset CHID
1552 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].checked = 0;
1553 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].status = 0;
1554 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].tries = 0xFE;
1555 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].streams = 0; // reset streams!
1556 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].irdeto_curindex = 0xFE; // reset
1557 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].irdeto_maxindex = 0; // reset
1558 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].irdeto_cycle = 0xFE; // reset
1559 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].table = 0;
1560
1561 cs_log("Demuxer %d ecmpid %d CAID: %04X ECM_PID: %04X PROVID: %06X %s", demux_id, demux[demux_id].ECMpidcount, caid, ecmpid, provid, txt);
1562 if(caid_is_irdeto(caid)) { demux[demux_id].emmstart.time = 1; } // marker to fetch emms early irdeto needs them!
1563
1564 demux[demux_id].ECMpidcount++;
1565}
1566
1567void dvbapi_add_ecmpid(int32_t demux_id, uint16_t caid, uint16_t ecmpid, uint32_t provid, char *txt)
1568{
1569 dvbapi_add_ecmpid_int(demux_id, caid, ecmpid, provid, txt);
1570 struct s_dvbapi_priority *joinentry;
1571
1572 for(joinentry = dvbapi_priority; joinentry != NULL; joinentry = joinentry->next)
1573 {
1574 if((joinentry->type != 'j')
1575 || (joinentry->caid && joinentry->caid != caid)
1576 || (joinentry->provid && joinentry->provid != provid)
1577 || (joinentry->ecmpid && joinentry->ecmpid != ecmpid)
1578 || (joinentry->srvid && joinentry->srvid != demux[demux_id].program_number))
1579 { continue; }
1580 cs_log_dbg(D_DVBAPI, "Join ecmpid %04X@%06X:%04X to %04X@%06X:%04X",
1581 caid, provid, ecmpid, joinentry->mapcaid, joinentry->mapprovid, joinentry->mapecmpid);
1582 dvbapi_add_ecmpid_int(demux_id, joinentry->mapcaid, joinentry->mapecmpid, joinentry->mapprovid, txt);
1583 }
1584}
1585
1586void dvbapi_add_emmpid(int32_t demux_id, uint16_t caid, uint16_t emmpid, uint32_t provid, uint8_t type)
1587{
1588 char typetext[40];
1589 cs_strncpy(typetext, ":", sizeof(typetext));
1590
1591 if(type & 0x01) { strcat(typetext, "UNIQUE:"); }
1592 if(type & 0x02) { strcat(typetext, "SHARED:"); }
1593 if(type & 0x04) { strcat(typetext, "GLOBAL:"); }
1594 if(type & 0xF8) { strcat(typetext, "UNKNOWN:"); }
1595
1596 uint16_t i;
1597 for(i = 0; i < demux[demux_id].EMMpidcount; i++)
1598 {
1599 if(demux[demux_id].EMMpids[i].PID == emmpid && demux[demux_id].EMMpids[i].CAID == caid && demux[demux_id].EMMpids[i].PROVID == provid)
1600 {
1601 if(!(demux[demux_id].EMMpids[i].type&type)){
1602 demux[demux_id].EMMpids[i].type |= type; // register this emm kind to this emmpid
1603 cs_log_dbg(D_DVBAPI, "Added to existing emmpid %d additional emmtype %s", demux[demux_id].EMMpidcount - 1, typetext);
1604 }
1605 return;
1606 }
1607 }
1608 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].PID = emmpid;
1609 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].CAID = caid;
1610 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].PROVID = provid;
1611 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount++].type = type;
1612 cs_log_dbg(D_DVBAPI, "Added new emmpid %d CAID: %04X EMM_PID: %04X PROVID: %06X TYPE %s", demux[demux_id].EMMpidcount - 1, caid, emmpid, provid, typetext);
1613}
1614
1615void dvbapi_parse_cat(int32_t demux_id, uchar *buf, int32_t len)
1616{
1617#if defined WITH_COOLAPI || defined WITH_COOLAPI2
1618 // driver sometimes reports error if too many emm filter
1619 // but adding more ecm filter is no problem
1620 // ... so ifdef here instead of limiting MAX_FILTER
1621 demux[demux_id].max_emm_filter = 14;
1622#else
1623 if(cfg.dvbapi_requestmode == 1)
1624 {
1625 uint16_t ecm_filter_needed = 0, n;
1626 for(n = 0; n < demux[demux_id].ECMpidcount; n++)
1627 {
1628 if(demux[demux_id].ECMpids[n].status > -1)
1629 { ecm_filter_needed++; }
1630 }
1631 if(maxfilter - ecm_filter_needed <= 0)
1632 { demux[demux_id].max_emm_filter = 0; }
1633 else
1634 { demux[demux_id].max_emm_filter = maxfilter - ecm_filter_needed; }
1635 }
1636 else
1637 {
1638 demux[demux_id].max_emm_filter = maxfilter - 1;
1639 }
1640#endif
1641 uint16_t i, k;
1642
1643 cs_log_dump_dbg(D_DVBAPI, buf, len, "cat:");
1644
1645 for(i = 8; i < (b2i(2, buf + 1)&0xFFF) - 1; i += buf[i + 1] + 2)
1646 {
1647 if(buf[i] != 0x09) { continue; }
1648 if(demux[demux_id].EMMpidcount >= ECM_PIDS) { break; }
1649
1650 uint16_t caid = b2i(2, buf + i + 2);
1651 uint16_t emm_pid = b2i(2, buf + i +4)&0x1FFF;
1652 uint32_t emm_provider = 0;
1653
1654 switch(caid >> 8)
1655 {
1656 case 0x01:
1657 dvbapi_add_emmpid(demux_id, caid, emm_pid, 0, EMM_UNIQUE | EMM_GLOBAL);
1658 for(k = i + 7; k < i + buf[i + 1] + 2; k += 4)
1659 {
1660 emm_provider = b2i(2, buf + k + 2);
1661 emm_pid = b2i(2, buf + k)&0xFFF;
1662 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, EMM_SHARED);
1663 }
1664 break;
1665 case 0x05:
1666 for(k = i + 6; k < i + buf[i + 1] + 2; k += buf[k + 1] + 2)
1667 {
1668 if (buf[k] == 0x14)
1669 {
1670 emm_provider = (b2i(3, buf + k + 2) & 0xFFFFF0); // viaccess fixup last digit is a dont care!
1671 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1672 }
1673 }
1674 break;
1675 case 0x18:
1676 if(buf[i + 1] == 0x07 || buf[i + 1] == 0x0B)
1677 {
1678 for(k = i + 7; k < i + 7 + buf[i + 6]; k += 2)
1679 {
1680 emm_provider = b2i(2, buf + k);
1681 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1682 }
1683 }
1684 else
1685 {
1686 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1687 }
1688 break;
1689 default:
1690 dvbapi_add_emmpid(demux_id, caid, emm_pid, 0, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1691 break;
1692 }
1693 }
1694 return;
1695}
1696
1697ca_index_t dvbapi_get_descindex(int32_t demux_index, int32_t pid, int32_t stream_id)
1698{
1699 int32_t i, j, k, fail = 1;
1700 ca_index_t idx = 0;
1701 uint32_t tmp_idx;
1702
1703 static pthread_mutex_t lockindex;
1704 static int8_t init_mutex = 0;
1705
1706 if(init_mutex == 0)
1707 {
1708 SAFE_MUTEX_INIT(&lockindex, NULL);
1709 init_mutex = 1;
1710 }
1711
1712 if(cfg.dvbapi_boxtype == BOXTYPE_NEUMO)
1713 {
1714 tmp_idx = 0;
1715 sscanf(demux[demux_index].pmt_file, "pmt%3d.tmp", &tmp_idx);
1716 return (ca_index_t)tmp_idx;
1717 }
1718
1719 SAFE_MUTEX_LOCK(&lockindex); // to avoid race when readers become responsive!
1720
1721 while(fail && idx <= INDEX_MAX)
1722 {
1723 fail = 0;
1724 for(i = 0; i < MAX_DEMUX && !fail && idx <= INDEX_MAX; i++)
1725 {
1726 if(demux[i].program_number == 0) { continue; } // skip empty demuxers
1727
1728 if(demux[i].ca_mask != demux[demux_index].ca_mask && (!(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)))
1729 {
1730 continue; // skip demuxer using other ca device
1731 }
1732
1733 for(j = 0; j < demux[i].ECMpidcount && !fail; j++) // search for new unique index
1734 {
1735 for(k = 0; k < MAX_STREAM_INDICES; k++)
1736 {
1737 if(demux[i].ECMpids[j].index[k] == idx)
1738 {
1739 fail = 1;
1740 idx++;
1741 }
1742 }
1743 }
1744 }
1745 }
1746
1747 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
1748 {
1749 if(idx > INDEX_MAX_NET)
1750 {
1751 idx = INDEX_INVALID;
1752 }
1753 }
1754 else
1755 {
1756 if(idx > INDEX_MAX_LOCAL)
1757 {
1758 idx = INDEX_INVALID;
1759 }
1760 }
1761
1762 demux[demux_index].ECMpids[pid].index[stream_id] = idx;
1763 SAFE_MUTEX_UNLOCK(&lockindex); // and release it!
1764 return idx;
1765}
1766
1767void dvbapi_set_pid(int32_t demux_id, int32_t num, ca_index_t idx, bool enable, bool use_des)
1768{
1769 int32_t i, currentfd;
1770 uint16_t streampid = demux[demux_id].STREAMpids[num];
1771 ca_index_t newidx = 0, curidx;
1772 ca_pid_t ca_pid2;
1773
1774 if(demux[demux_id].pidindex == -1 && enable) return; // no current pid on enable? --> exit
1775
1776 switch(selected_api)
1777 {
1778#if defined(WITH_STAPI) || defined(WITH_STAPI5)
1779 case STAPI:
1780 if(!enable) idx = INDEX_INVALID;
1781 stapi_set_pid(demux_id, num, idx, streampid, demux[demux_id].pmt_file); // only used to disable pids!!!
1782 break;
1783#endif
1784#if defined WITH_COOLAPI || defined WITH_COOLAPI2
1785 case COOLAPI:
1786 break;
1787#endif
1788 default:
1789 for(i = 0; i < MAX_DEMUX; i++)
1790 {
1791 newidx = INDEX_INVALID, curidx = idx;
1792 if(((demux[demux_id].ca_mask & (1 << i)) == (uint32_t) (1 << i)))
1793 {
1794 uint32_t action = 0;
1795 if(enable){
1796 action = update_streampid_list(i, streampid, curidx, use_des);
1797 }
1798 if(!enable){
1799 action = remove_streampid_from_list(i, streampid, curidx);
1800 }
1801
1802 if(action != NO_STREAMPID_LISTED && action != INVALID_STREAMPID_INDEX && action != FOUND_STREAMPID_INDEX && action != ADDED_STREAMPID_INDEX && action != REMOVED_STREAMPID_INDEX)
1803 {
1804 // removed last of this streampid on ca? -> disable this pid with -1 on this ca
1805 if((action == REMOVED_STREAMPID_LASTINDEX || action == FIRST_STREAMPID_INDEX) && (is_ca_used(i, streampid) == INDEX_INVALID)) curidx = DVBAPI_INDEX_DISABLE;
1806
1807 // removed index of streampid that is used to decode on ca -> get a fresh one
1808 if(action == REMOVED_DECODING_STREAMPID_INDEX || action == FIRST_STREAMPID_INDEX)
1809 {
1810 newidx = is_ca_used(i, streampid); // get an active index for this pid and enable it on ca device
1811 curidx = DVBAPI_INDEX_DISABLE;
1812 }
1813
1814 while (curidx != INDEX_INVALID || newidx != INDEX_INVALID)
1815 {
1816 memset(&ca_pid2, 0, sizeof(ca_pid2));
1817 ca_pid2.pid = streampid;
1818
1819 if(curidx != INDEX_INVALID)
1820 {
1821 (curidx == DVBAPI_INDEX_DISABLE) ? (ca_pid2.index = -1) : (ca_pid2.index = curidx);
1822 cs_log_dbg(D_DVBAPI, "Demuxer %d %s stream %d pid=0x%04x index=%d on ca%d", demux_id,
1823 ((enable && curidx != DVBAPI_INDEX_DISABLE) ? "enable" : "disable"), num + 1, ca_pid2.pid, ca_pid2.index, i);
1824 curidx = INDEX_INVALID; // flag this index as handled
1825 }
1826 else if (newidx != INDEX_INVALID)
1827 {
1828 (newidx == DVBAPI_INDEX_DISABLE) ? (ca_pid2.index = -1) : (ca_pid2.index = newidx);
1829
1830 cs_log_dbg(D_DVBAPI, "Demuxer %d %s stream %d pid=0x%04x by index=%d on ca%d", demux_id,
1831 ((enable && action == FIRST_STREAMPID_INDEX) ? "enable" : "takeover"), num + 1, ca_pid2.pid, ca_pid2.index, i);
1832
1833 newidx = INDEX_INVALID; // flag this takeover / new index as handled
1834 }
1835
1836 if(use_des && cfg.dvbapi_extended_cw_api == 2 && ca_pid2.index != -1)
1837 {
1838 ca_pid2.index |= 0x100;
1839 }
1840
1841 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
1842 dvbapi_net_send(DVBAPI_CA_SET_PID, demux[demux_id].socket_fd, demux_id, -1 /*unused*/, (unsigned char *) &ca_pid2, NULL, NULL, demux[demux_id].client_proto_version);
1843 else
1844 {
1845 currentfd = ca_fd[i];
1846 if(currentfd <= 0)
1847 {
1848 currentfd = dvbapi_open_device(1, i, demux[demux_id].adapter_index);
1849 ca_fd[i] = currentfd; // save fd of this ca
1850 }
1851 if(currentfd > 0)
1852 {
1853 if(dvbapi_ioctl(currentfd, CA_SET_PID, &ca_pid2) == -1)
1854 {
1855 cs_log_dbg(D_TRACE | D_DVBAPI,"CA_SET_PID ioctl error (errno=%d %s)", errno, strerror(errno));
1856 remove_streampid_from_list(i, ca_pid2.pid, INDEX_DISABLE_ALL);
1857 }
1858 ca_index_t result = is_ca_used(i,0); // check if in use by any pid
1859 if(result == INDEX_INVALID)
1860 {
1861 cs_log_dbg(D_DVBAPI, "Demuxer %d close now unused CA%d device", demux_id, i);
1862 int32_t ret = close(currentfd);
1863 if(ret < 0) { cs_log("ERROR: Could not close demuxer fd (errno=%d %s)", errno, strerror(errno)); }
1864 currentfd = ca_fd[i] = 0;
1865 }
1866 }
1867 }
1868 }
1869 }
1870 }
1871 }
1872 break;
1873 }
1874 return;
1875}
1876
1877void dvbapi_stop_all_descrambling(void)
1878{
1879 int32_t j;
1880 for(j = 0; j < MAX_DEMUX; j++)
1881 {
1882 if(demux[j].program_number == 0) { continue; }
1883 dvbapi_stop_descrambling(j);
1884 }
1885}
1886
1887void dvbapi_stop_all_emm_sdt_filtering(void)
1888{
1889 int32_t j;
1890 for(j = 0; j < MAX_DEMUX; j++)
1891 {
1892 if(demux[j].program_number == 0) { continue; }
1893 dvbapi_stop_filter(j, TYPE_EMM);
1894 dvbapi_stop_filter(j, TYPE_SDT);
1895 demux[j].emm_filter = -1;
1896 }
1897}
1898
1899
1900void dvbapi_stop_descrambling(int32_t demux_id)
1901{
1902 int32_t i, j, z;
1903 if(demux[demux_id].program_number == 0) { return; }
1904 char channame[CS_SERVICENAME_SIZE];
1905 i = demux[demux_id].pidindex;
1906 if(i < 0) { i = 0; }
1907 demux[demux_id].pidindex = -1; // no ecmpid is to be descrambling since we start stop descrambling!
1908 get_servicename(dvbapi_client, demux[demux_id].program_number, demux[demux_id].ECMpidcount > 0 ? demux[demux_id].ECMpids[i].PROVID : NO_PROVID_VALUE, demux[demux_id].ECMpidcount > 0 ? demux[demux_id].ECMpids[i].CAID : NO_CAID_VALUE, channame, sizeof(channame));
1909 cs_log("Demuxer %d stop descrambling program number %04X (%s)", demux_id, demux[demux_id].program_number, channame);
1910
1911 dvbapi_stop_filter(demux_id, TYPE_EMM);
1912 dvbapi_stop_filter(demux_id, TYPE_SDT);
1913 dvbapi_stop_filter(demux_id, TYPE_PAT);
1914 dvbapi_stop_filter(demux_id, TYPE_PMT);
1915
1916 for(i = 0; i < demux[demux_id].ECMpidcount && demux[demux_id].ECMpidcount > 0; i++)
1917 {
1918 for(j = 0; j < MAX_STREAM_INDICES; j++)
1919 {
1920 if(demux[demux_id].ECMpids[i].index[j] == INDEX_INVALID) continue;
1921
1922 // disable streams!
1923 for(z = 0; z < demux[demux_id].STREAMpidcount; z++)
1924 {
1925 dvbapi_set_pid(demux_id, z, demux[demux_id].ECMpids[i].index[j], false, false); // disable streampid
1926 }
1927 demux[demux_id].ECMpids[i].index[j] = INDEX_INVALID;
1928 }
1929 }
1930 dvbapi_stop_filter(demux_id, TYPE_ECM);
1931
1932 memset(&demux[demux_id], 0 , sizeof(DEMUXTYPE));
1933 for(i = 0; i < ECM_PIDS; i++)
1934 {
1935 for(j = 0; j < MAX_STREAM_INDICES; j++)
1936 {
1937 demux[demux_id].ECMpids[i].index[j] = INDEX_INVALID;
1938 }
1939 }
1940
1941 demux[demux_id].pidindex = -1;
1942 demux[demux_id].curindex = -1;
1943 if (!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX)
1944 unlink(ECMINFO_FILE);
1945 return;
1946}
1947
1948int32_t dvbapi_start_descrambling(int32_t demux_id, int32_t pid, int8_t checked)
1949{
1950 int32_t started = 0; // in case ecmfilter started = 1
1951 int32_t fake_ecm = 0;
1952 ECM_REQUEST *er;
1953 struct s_reader *rdr;
1954 if(!(er = get_ecmtask())) { return started; }
1955 demux[demux_id].ECMpids[pid].checked = checked + 1; // mark this pid as checked!
1956
1957 struct s_dvbapi_priority *p;
1958 for(p = dvbapi_priority; p != NULL ; p = p->next)
1959 {
1960 if((p->type != 'p')
1961 || (p->caid && p->caid != demux[demux_id].ECMpids[pid].CAID)
1962 || (p->provid && p->provid != demux[demux_id].ECMpids[pid].PROVID)
1963 || (p->ecmpid && p->ecmpid != demux[demux_id].ECMpids[pid].ECM_PID)
1964 || (p->srvid && p->srvid != demux[demux_id].program_number)
1965 || (p->pidx && p->pidx-1 != pid))
1966 { continue; }
1967 // if found chid and first run apply chid filter, on forced pids always apply!
1968 if(p->type == 'p' && p->chid < 0x10000 && (demux[demux_id].ECMpids[pid].checked == 1 || (p && p->force)))
1969 {
1970 if(demux[demux_id].ECMpids[pid].CHID < 0x10000) // channelcache delivered chid
1971 {
1972 er->chid = demux[demux_id].ECMpids[pid].CHID;
1973 }
1974 else
1975 {
1976 er->chid = p->chid; // no channelcache or no chid in use, so use prio chid
1977 demux[demux_id].ECMpids[pid].CHID = p->chid;
1978 }
1979 //cs_log("********* CHID %04X **************", demux[demux_id].ECMpids[pid].CHID);
1980 break; // we only accept one!
1981 }
1982 else
1983 {
1984 if(demux[demux_id].ECMpids[pid].CHID < 0x10000) // channelcache delivered chid
1985 {
1986 er->chid = demux[demux_id].ECMpids[pid].CHID;
1987 }
1988 else // no channelcache or no chid in use
1989 {
1990 er->chid = 0;
1991 demux[demux_id].ECMpids[pid].CHID = 0x10000;
1992 }
1993 }
1994 }
1995 er->srvid = demux[demux_id].program_number;
1996 er->caid = demux[demux_id].ECMpids[pid].CAID;
1997 er->pid = demux[demux_id].ECMpids[pid].ECM_PID;
1998 er->prid = demux[demux_id].ECMpids[pid].PROVID;
1999 er->vpid = demux[demux_id].ECMpids[pid].VPID;
2000 er->pmtpid = demux[demux_id].pmtpid;
2001
2002#ifdef WITH_STAPI5
2003 cs_strncpy(er->dev_name, dev_list[demux[demux_id].dev_index].name, sizeof(dev_list[demux[demux_id].dev_index].name));
2004#endif
2005
2006 struct timeb now;
2007 cs_ftime(&now);
2008 for(rdr = first_active_reader; rdr != NULL ; rdr = rdr->next)
2009 {
2010 int8_t match = matching_reader(er, rdr); // check for matching reader
2011 int64_t gone = comp_timeb(&now, &rdr->emm_last);
2012 if(gone > 3600*1000 && rdr->needsemmfirst && caid_is_irdeto(er->caid))
2013 {
2014 cs_log("Warning reader %s received no emms for the last %d seconds -> skip, this reader needs emms first!", rdr->label,
2015 (int)(gone/1000));
2016 continue; // skip this card needs to process emms first before it can be used for descramble
2017 }
2018 if(p && p->force) { match = 1; } // forced pid always started!
2019
2020 if(!match) // if this reader does not match, check betatunnel for it
2021 match = lb_check_auto_betatunnel(er, rdr);
2022
2023 if(!match && chk_is_betatunnel_caid(er->caid)) // these caids might be tunneled invisible by peers
2024 { match = 1; } // so make it a match to try it!
2025
2026 if(config_enabled(CS_CACHEEX) && (!match && (cacheex_is_match_alias(dvbapi_client, er)))) // check if cache-ex is matching
2027 {
2028 match = 1; // so make it a match to try it!
2029 }
2030
2031 // BISS or FAKE CAID
2032 // ecm stream pid is fake, so send out one fake ecm request
2033 // special treatment: if we asked the cw first without starting a filter the cw request will be killed due to no ecmfilter started
2034 if(caid_is_fake(demux[demux_id].ECMpids[pid].CAID) || caid_is_biss(demux[demux_id].ECMpids[pid].CAID))
2035 {
2036 int32_t j, n;
2037 er->ecmlen = 5;
2038 er->ecm[0] = 0x80; // to pass the cache check it must be 0x80 or 0x81
2039 er->ecm[1] = 0x00;
2040 er->ecm[2] = 0x02;
2041 i2b_buf(2, er->srvid, er->ecm + 3);
2042
2043 for(j = 0, n = 5; j < demux[demux_id].STREAMpidcount; j++, n += 2)
2044 {
2045 i2b_buf(2, demux[demux_id].STREAMpids[j], er->ecm + n);
2046 er->ecm[2] += 2;
2047 er->ecmlen += 2;
2048 }
2049
2050 cs_log("Demuxer %d trying to descramble PID %d CAID %04X PROVID %06X ECMPID %04X ANY CHID PMTPID %04X VPID %04X", demux_id, pid,
2051 demux[demux_id].ECMpids[pid].CAID, demux[demux_id].ECMpids[pid].PROVID, demux[demux_id].ECMpids[pid].ECM_PID,
2052 demux[demux_id].pmtpid, demux[demux_id].ECMpids[pid].VPID);
2053
2054 demux[demux_id].curindex = pid; // set current pid to the fresh started one
2055
2056 dvbapi_start_filter(demux_id, pid, demux[demux_id].ECMpids[pid].ECM_PID, demux[demux_id].ECMpids[pid].CAID,
2057 demux[demux_id].ECMpids[pid].PROVID, 0x80, 0xF0, 3000, TYPE_ECM);
2058 started = 1;
2059
2060 request_cw(dvbapi_client, er, demux_id, 0); // do not register ecm since this try!
2061 fake_ecm = 1;
2062 break; // we started an ecmfilter so stop looking for next matching reader!
2063 }
2064 if(match) // if matching reader found check for irdeto cas if local irdeto card check if it received emms in last 60 minutes
2065 {
2066
2067 if(caid_is_irdeto(er->caid)) // irdeto cas init irdeto_curindex to wait for first index (00)
2068 {
2069 if(demux[demux_id].ECMpids[pid].irdeto_curindex == 0xFE) { demux[demux_id].ECMpids[pid].irdeto_curindex = 0x00; }
2070 }
2071
2072 if(p && p->chid < 0x10000) // do we prio a certain chid?
2073 {
2074 cs_log("Demuxer %d trying to descramble PID %d CAID %04X PROVID %06X ECMPID %04X CHID %04X PMTPID %04X VPID %04X", demux_id, pid,
2075 demux[demux_id].ECMpids[pid].CAID, demux[demux_id].ECMpids[pid].PROVID, demux[demux_id].ECMpids[pid].ECM_PID,
2076 demux[demux_id].ECMpids[pid].CHID, demux[demux_id].pmtpid, demux[demux_id].ECMpids[pid].VPID);
2077 }
2078 else
2079 {
2080 cs_log("Demuxer %d trying to descramble PID %d CAID %04X PROVID %06X ECMPID %04X ANY CHID PMTPID %04X VPID %04X", demux_id, pid,
2081 demux[demux_id].ECMpids[pid].CAID, demux[demux_id].ECMpids[pid].PROVID, demux[demux_id].ECMpids[pid].ECM_PID,
2082 demux[demux_id].pmtpid, demux[demux_id].ECMpids[pid].VPID);
2083 }
2084
2085 demux[demux_id].curindex = pid; // set current pid to the fresh started one
2086
2087 dvbapi_start_filter(demux_id, pid, demux[demux_id].ECMpids[pid].ECM_PID, demux[demux_id].ECMpids[pid].CAID,
2088 demux[demux_id].ECMpids[pid].PROVID, 0x80, 0xF0, 3000, TYPE_ECM);
2089 started = 1;
2090 break; // we started an ecmfilter so stop looking for next matching reader!
2091 }
2092 }
2093 if(demux[demux_id].curindex != pid)
2094 {
2095 cs_log("Demuxer %d impossible to descramble PID %d CAID %04X PROVID %06X ECMPID %04X PMTPID %04X (NO MATCHING READER)", demux_id, pid,
2096 demux[demux_id].ECMpids[pid].CAID, demux[demux_id].ECMpids[pid].PROVID, demux[demux_id].ECMpids[pid].ECM_PID, demux[demux_id].pmtpid);
2097 demux[demux_id].ECMpids[pid].checked = 4; // flag this pid as checked
2098 demux[demux_id].ECMpids[pid].status = -1; // flag this pid as unusable
2099 dvbapi_edit_channel_cache(demux_id, pid, 0); // remove this pid from channelcache
2100 }
2101 if(!fake_ecm) { NULLFREE(er); }
2102 return started;
2103}
2104
2105struct s_dvbapi_priority *dvbapi_check_prio_match_emmpid(int32_t demux_id, uint16_t caid, uint32_t provid, char type)
2106{
2107 struct s_dvbapi_priority *p;
2108 int32_t i;
2109
2110 uint16_t ecm_pid = 0;
2111 for(i = 0; i < demux[demux_id].ECMpidcount; i++)
2112 {
2113 if((demux[demux_id].ECMpids[i].CAID == caid) && (demux[demux_id].ECMpids[i].PROVID == provid))
2114 {
2115 ecm_pid = demux[demux_id].ECMpids[i].ECM_PID;
2116 break;
2117 }
2118 }
2119
2120 if(!ecm_pid)
2121 { return NULL; }
2122
2123 for(p = dvbapi_priority; p != NULL; p = p->next)
2124 {
2125 if(p->type != type
2126 || (p->caid && p->caid != caid)
2127 || (p->provid && p->provid != provid)
2128 || (p->ecmpid && p->ecmpid != ecm_pid)
2129 || (p->srvid && p->srvid != demux[demux_id].program_number)
2130 || (p->pidx && p->pidx-1 !=i)
2131 || (p->type == 'i' && (p->chid < 0x10000)))
2132 { continue; }
2133 return p;
2134 }
2135 return NULL;
2136}
2137
2138struct s_dvbapi_priority *dvbapi_check_prio_match(int32_t demux_id, int32_t pidindex, char type)
2139{
2140 if(!dvbapi_priority)
2141 {
2142 return NULL;
2143 }
2144 struct s_dvbapi_priority *p;
2145 struct s_ecmpids *ecmpid = &demux[demux_id].ECMpids[pidindex];
2146
2147 for(p = dvbapi_priority; p != NULL; p = p->next)
2148 {
2149 if(p->type != type
2150 || (p->caid && p->caid != ecmpid->CAID)
2151 || (p->provid && p->provid != ecmpid->PROVID)
2152 || (p->ecmpid && p->ecmpid != ecmpid->ECM_PID)
2153 || (p->srvid && p->srvid != demux[demux_id].program_number)
2154 || (p->pidx && p->pidx-1 != pidindex)
2155 || (p->chid < 0x10000 && p->chid != ecmpid->CHID))
2156 { continue; }
2157 return p;
2158 }
2159 return NULL;
2160}
2161
2162void dvbapi_process_emm(int32_t demux_index, int32_t filter_num, unsigned char *buffer, uint32_t len)
2163{
2164 EMM_PACKET epg;
2165
2166 struct s_emm_filter *filter = get_emmfilter_by_filternum(demux_index, filter_num+1); // 0 is used for pending emmfilters, so everything increase 1
2167
2168 if(!filter)
2169 {
2170 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d no filter matches -> SKIP!", demux_index, filter_num +1);
2171 return;
2172 }
2173
2174 uint32_t provider = filter->provid;
2175 uint16_t caid = filter->caid;
2176
2177 struct s_dvbapi_priority *mapentry = dvbapi_check_prio_match_emmpid(filter->demux_id, filter->caid, filter->provid, 'm');
2178 if(mapentry)
2179 {
2180 cs_log_dbg(D_DVBAPI, "Demuxer %d mapping EMM from %04X@%06X to %04X@%06X", demux_index, caid, provider, mapentry->mapcaid,
2181 mapentry->mapprovid);
2182 caid = mapentry->mapcaid;
2183 provider = mapentry->mapprovid;
2184 }
2185
2186 memset(&epg, 0, sizeof(epg));
2187
2188 i2b_buf(2, caid, epg.caid);
2189 i2b_buf(4, provider, epg.provid);
2190
2191 epg.emmlen = len > sizeof(epg.emm) ? sizeof(epg.emm) : len;
2192 memcpy(epg.emm, buffer, epg.emmlen);
2193
2194 if(config_enabled(READER_IRDETO) && chk_is_betatunnel_caid(caid) == 2)
2195 {
2196 uint16_t ncaid = tunemm_caid_map(FROM_TO, caid, demux[demux_index].program_number);
2197 if(caid != ncaid)
2198 {
2199 irdeto_add_emm_header(&epg);
2200 i2b_buf(2, ncaid, epg.caid);
2201 }
2202 }
2203
2204 do_emm(dvbapi_client, &epg);
2205}
2206
2207void dvbapi_read_priority(void)
2208{
2209 FILE *fp;
2210 char token[128], str1[128];
2211 char type;
2212 int32_t i, ret, count = 0;
2213
2214 const char *cs_prio = "oscam.dvbapi";
2215
2216 fp = fopen(get_config_filename(token, sizeof(token), cs_prio), "r");
2217
2218 if(!fp)
2219 {
2220 cs_log_dbg(D_DVBAPI, "ERROR: Can't open priority file %s", token);
2221 return;
2222 }
2223
2224 if(dvbapi_priority)
2225 {
2226 cs_log_dbg(D_DVBAPI, "reread priority file %s", cs_prio);
2227 struct s_dvbapi_priority *o, *p;
2228 for(p = dvbapi_priority; p != NULL; p = o)
2229 {
2230 o = p->next;
2231 NULLFREE(p);
2232 }
2233 dvbapi_priority = NULL;
2234 }
2235
2236 while(fgets(token, sizeof(token), fp))
2237 {
2238 // Ignore comments and empty lines
2239 if(token[0] == '#' || token[0] == '/' || token[0] == '\n' || token[0] == '\r' || token[0] == '\0')
2240 { continue; }
2241 if(strlen(token) > 100) { continue; }
2242
2243 memset(str1, 0, 128);
2244
2245 for(i = 0; i < (int)strlen(token) && token[i] == ' '; i++) { ; }
2246 if(i == (int)strlen(token) - 1) //empty line or all spaces
2247 { continue; }
2248
2249 for(i = 0; i < (int)strlen(token); i++)
2250 {
2251 if(token[i] == '@')
2252 {
2253 token[i] = ':';
2254 }
2255 }
2256
2257 for(i = 0; i < (int)strlen(token); i++)
2258 {
2259 if((token[i] == ':' || token[i] == ' ') && token[i + 1] == ':') // if "::" or " :"
2260 {
2261 memmove(token + i + 2, token + i + 1, strlen(token) - i + 1); //insert extra position
2262 token[i + 1] = '0'; //and fill it with NULL
2263 }
2264 if(token[i] == '#' || token[i] == '/')
2265 {
2266 token[i] = '\0';
2267 break;
2268 }
2269 }
2270
2271 type = 0;
2272#if defined(WITH_STAPI) || defined(WITH_STAPI5)
2273 uint32_t disablefilter = 0;
2274 ret = sscanf(trim(token), "%c: %63s %63s %d", &type, str1, str1 + 64, &disablefilter);
2275#else
2276 ret = sscanf(trim(token), "%c: %63s %63s", &type, str1, str1 + 64);
2277#endif
2278 type = tolower((uchar)type);
2279
2280 if(ret < 1 || (type != 'p' && type != 'i' && type != 'm' && type != 'd' && type != 's' && type != 'l'
2281 && type != 'j' && type != 'a' && type != 'x'))
2282 {
2283 //fprintf(stderr, "Warning: line containing %s in %s not recognized, ignoring line\n", token, cs_prio);
2284 //fprintf would issue the warning to the command line, which is more consistent with other config warnings
2285 //however it takes OSCam a long time (>4 seconds) to reach this part of the program, so the warnings are reaching tty rather late
2286 //which leads to confusion. So send the warnings to log file instead
2287 cs_log_dbg(D_DVBAPI, "WARN: line containing %s in %s not recognized, ignoring line\n", token, cs_prio);
2288 continue;
2289 }
2290
2291 struct s_dvbapi_priority *entry;
2292 if(!cs_malloc(&entry, sizeof(struct s_dvbapi_priority)))
2293 {
2294 ret = fclose(fp);
2295 if(ret < 0) { cs_log("ERROR: Could not close oscam.dvbapi fd (errno=%d %s)", errno, strerror(errno)); }
2296 return;
2297 }
2298
2299 entry->type = type;
2300 entry->next = NULL;
2301
2302 count++;
2303
2304#if defined(WITH_STAPI) || defined(WITH_STAPI5)
2305 if(type == 's')
2306 {
2307 strncpy(entry->devname, str1, 29);
2308 strncpy(entry->pmtfile, str1 + 64, 29);
2309
2310 entry->disablefilter = disablefilter;
2311
2312 cs_log_dbg(D_DVBAPI, "stapi prio: ret=%d | %c: %s %s | disable %d",
2313 ret, type, entry->devname, entry->pmtfile, disablefilter);
2314
2315 if(!dvbapi_priority)
2316 {
2317 dvbapi_priority = entry;
2318 }
2319 else
2320 {
2321 struct s_dvbapi_priority *p;
2322 for(p = dvbapi_priority; p->next != NULL; p = p->next) { ; }
2323 p->next = entry;
2324 }
2325 continue;
2326 }
2327#endif
2328
2329 char c_srvid[34];
2330 c_srvid[0] = '\0';
2331 uint32_t caid = 0, provid = 0, srvid = 0, ecmpid = 0;
2332 uint32_t chid = 0x10000; //chid=0 is a valid chid
2333 ret = sscanf(str1, "%4x:%6x:%33[^:]:%4x:%4x"SCNx16, &caid, &provid, c_srvid, &ecmpid, &chid);
2334 if(ret < 1)
2335 {
2336 cs_log("Error in oscam.dvbapi: ret=%d | %c: %04X %06X %s %04X %04X",
2337 ret, type, caid, provid, c_srvid, ecmpid, chid);
2338 continue; // skip this entry!
2339 }
2340 else
2341 {
2342 cs_log_dbg(D_DVBAPI, "Parsing rule: ret=%d | %c: %04X %06X %s %04X %04X",
2343 ret, type, caid, provid, c_srvid, ecmpid, chid);
2344 }
2345
2346 entry->caid = caid;
2347 entry->provid = provid;
2348 entry->ecmpid = ecmpid;
2349 entry->chid = chid;
2350
2351 uint32_t delay = 0, force = 0, mapcaid = 0, mapprovid = 0, mapecmpid = 0, pidx = 0;
2352 switch(type)
2353 {
2354 case 'i':
2355 ret = sscanf(str1 + 64, "%1d", &pidx);
2356 entry->pidx = pidx+1;
2357 if(ret < 1) entry->pidx = 0;
2358 break;
2359 case 'd':
2360 sscanf(str1 + 64, "%4d", &delay);
2361 entry->delay = delay;
2362 break;
2363 case 'l':
2364 entry->delay = dyn_word_atob(str1 + 64);
2365 if(entry->delay == -1) { entry->delay = 0; }
2366 break;
2367 case 'p':
2368 ret = sscanf(str1 + 64, "%1d:%1d", &force, &pidx);
2369 entry->force = force;
2370 entry->pidx = pidx+1;
2371 if(ret < 2) entry->pidx = 0;
2372 break;
2373 case 'm':
2374 sscanf(str1 + 64, "%4x:%6x", &mapcaid, &mapprovid);
2375 if(!mapcaid) { mapcaid = 0xFFFF; }
2376 entry->mapcaid = mapcaid;
2377 entry->mapprovid = mapprovid;
2378 break;
2379 case 'a':
2380 case 'j':
2381 sscanf(str1 + 64, "%4x:%6x:%4x", &mapcaid, &mapprovid, &mapecmpid);
2382 if(!mapcaid) { mapcaid = 0xFFFF; }
2383 entry->mapcaid = mapcaid;
2384 entry->mapprovid = mapprovid;
2385 entry->mapecmpid = mapecmpid;
2386 break;
2387 }
2388
2389 if(c_srvid[0] == '=')
2390 {
2391 struct s_srvid *this;
2392
2393 for(i = 0; i < 16; i++)
2394 for(this = cfg.srvid[i]; this != NULL; this = this->next)
2395 {
2396 if(this->name && strcmp(this->name, c_srvid + 1) == 0)
2397 {
2398 struct s_dvbapi_priority *entry2;
2399 if(!cs_malloc(&entry2, sizeof(struct s_dvbapi_priority)))
2400 { continue; }
2401 memcpy(entry2, entry, sizeof(struct s_dvbapi_priority));
2402 entry2->srvid = this->srvid;
2403 cs_log_dbg(D_DVBAPI, "prio srvid: ret=%d | %c: %04X %06X %04X %04X %04X -> map %04X %06X %04X | prio %d | delay %d", ret, entry2->type, entry2->caid, entry2->provid, entry2->srvid, entry2->ecmpid, entry2->chid, entry2->mapcaid, entry2->mapprovid, entry2->mapecmpid, entry2->force, entry2->delay);
2404
2405 if(!dvbapi_priority)
2406 {
2407 dvbapi_priority = entry2;
2408 }
2409 else
2410 {
2411 struct s_dvbapi_priority *p;
2412 for(p = dvbapi_priority; p->next != NULL; p = p->next) { ; }
2413 p->next = entry2;
2414 }
2415 }
2416 }
2417 NULLFREE(entry);
2418 continue;
2419 }
2420 else
2421 {
2422 sscanf(c_srvid, "%4x", &srvid);
2423 entry->srvid = srvid;
2424 }
2425 cs_log_dbg(D_DVBAPI, "prio: ret=%d | %c: %04X %06X %04X %04X %04X -> map %04X %06X %04X | prio %d | delay %d", ret, entry->type, entry->caid, entry->provid, entry->srvid, entry->ecmpid, entry->chid, entry->mapcaid, entry->mapprovid, entry->mapecmpid, entry->force, entry->delay);
2426
2427 if(!dvbapi_priority)
2428 {
2429 dvbapi_priority = entry;
2430 }
2431 else
2432 {
2433 struct s_dvbapi_priority *p;
2434 for(p = dvbapi_priority; p->next != NULL; p = p->next) { ; }
2435 p->next = entry;
2436 }
2437 }
2438
2439 cs_log_dbg(D_DVBAPI, "Read %d entries from %s", count, cs_prio);
2440
2441 ret = fclose(fp);
2442 if(ret < 0) { cs_log("ERROR: Could not close oscam.dvbapi fd (errno=%d %s)", errno, strerror(errno)); }
2443 return;
2444}
2445
2446void dvbapi_resort_ecmpids(int32_t demux_index)
2447{
2448 int32_t n, cache = 0, matching_done = 0, found = -1, match_reader_count = 0, total_reader = 0;
2449 uint16_t btun_caid = 0;
2450 struct timeb start,end;
2451 cs_ftime(&start);
2452 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2453 {
2454 demux[demux_index].ECMpids[n].status = 0;
2455 demux[demux_index].ECMpids[n].checked = 0;
2456 demux[demux_index].ECMpids[n].irdeto_curindex = 0xFE;
2457 demux[demux_index].ECMpids[n].irdeto_maxindex = 0;
2458 demux[demux_index].ECMpids[n].irdeto_cycle = 0xFE;
2459 demux[demux_index].ECMpids[n].tries = 0xFE;
2460 demux[demux_index].ECMpids[n].table = 0;
2461 }
2462
2463 demux[demux_index].max_status = 0;
2464 demux[demux_index].curindex = -1;
2465 demux[demux_index].pidindex = -1;
2466
2467
2468 struct s_reader *rdr;
2469
2470 int32_t p_order = demux[demux_index].ECMpidcount+1;
2471 struct s_dvbapi_priority *prio;
2472
2473 // handle prio order in oscam.dvbapi + ignore all chids
2474
2475 for(rdr = first_active_reader; rdr ; rdr = rdr->next)
2476 {
2477 total_reader++; // only need to calculate once!
2478 }
2479
2480 ECM_REQUEST *er;
2481 if(!cs_malloc(&er, sizeof(ECM_REQUEST)))
2482 { return; }
2483
2484 for(prio = dvbapi_priority; prio != NULL; prio = prio->next)
2485 {
2486 if(prio->type != 'p' && prio->type != 'i' )
2487 { continue; }
2488 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2489 {
2490 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2491 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
2492 er->prid = demux[demux_index].ECMpids[n].PROVID;
2493 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
2494 er->srvid = demux[demux_index].program_number;
2495 er->client = cur_client();
2496 btun_caid = chk_on_btun(SRVID_MASK, er->client, er);
2497 if(prio->type == 'p' && btun_caid)
2498 {
2499 er->caid = btun_caid;
2500 }
2501
2502 if(prio->caid && (prio->caid != er->caid && prio->caid != er->ocaid)) { continue; }
2503 if(prio->provid && prio->provid != er->prid) { continue; }
2504 if(prio->srvid && prio->srvid != er->srvid) { continue; }
2505 if(prio->ecmpid && prio->ecmpid != er->pid) { continue; }
2506 if(prio->pidx && prio->pidx-1 != n) { continue; }
2507
2508 if(prio->type == 'p') // check for prio
2509 {
2510 if(prio->chid < 0x10000) { demux[demux_index].ECMpids[n].CHID = prio->chid; }
2511 if(prio->force)
2512 {
2513 int32_t j;
2514 for(j = 0; j < demux[demux_index].ECMpidcount; j++)
2515 {
2516 demux[demux_index].ECMpids[j].status = -1;
2517 }
2518 demux[demux_index].ECMpids[n].status = 1;
2519 demux[demux_index].ECMpids[n].checked = 0;
2520 demux[demux_index].max_status = 1;
2521 demux[demux_index].max_emm_filter = maxfilter - 1;
2522 cs_log_dbg(D_DVBAPI, "Demuxer %d prio forced%s ecmpid %d %04X@%06X:%04X:%04X (file)", demux_index,
2523 ((prio->caid == er->caid && prio->caid != er->ocaid) ? " betatunneled" : ""), n, demux[demux_index].ECMpids[n].CAID,
2524 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, (uint16_t) prio->chid);
2525 NULLFREE(er);
2526 return; // go start descrambling since its forced by user!
2527 }
2528 else
2529 {
2530 if(!demux[demux_index].ECMpids[n].status) // only accept first matching prio from oscam.dvbapi
2531 {
2532 demux[demux_index].ECMpids[n].status = total_reader + p_order--;
2533 matching_done = 1;
2534 cs_log_dbg(D_DVBAPI, "Demuxer %d prio%s ecmpid %d %04X@%06X:%04X:%04X weight: %d (file)", demux_index,
2535 ((prio->caid == er->caid && prio->caid != er->ocaid) ? " betatunneled" : ""), n, demux[demux_index].ECMpids[n].CAID,
2536 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, (uint16_t) prio->chid, demux[demux_index].ECMpids[n].status);
2537 }
2538 continue; // evaluate next ecmpid
2539 }
2540 }
2541 if(prio->type == 'i' && prio->chid == 0x10000 && demux[demux_index].ECMpids[n].status == 0) // check for ignore all chids
2542 {
2543 cs_log_dbg(D_DVBAPI, "Demuxer %d ignore ecmpid %d %04X@%06X:%04X all chids (file)", demux_index, n, demux[demux_index].ECMpids[n].CAID,
2544 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID);
2545 demux[demux_index].ECMpids[n].status = -1;
2546 continue; // evaluate next ecmpid
2547 }
2548 }
2549 }
2550
2551 p_order = demux[demux_index].ECMpidcount+1;
2552
2553 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2554 {
2555 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2556
2557 int32_t nr;
2558 SIDTAB *sidtab;
2559 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
2560 er->prid = demux[demux_index].ECMpids[n].PROVID;
2561 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
2562 er->srvid = demux[demux_index].program_number;
2563 er->client = cur_client();
2564 btun_caid = chk_on_btun(SRVID_MASK, er->client, er);
2565
2566 if(btun_caid)
2567 {
2568 er->caid = btun_caid;
2569 }
2570
2571 match_reader_count = 0;
2572 for(rdr = first_active_reader; rdr ; rdr = rdr->next)
2573 {
2574 if(matching_reader(er, rdr))
2575 {
2576 match_reader_count++;
2577 }
2578 }
2579
2580 if(match_reader_count == 0)
2581 {
2582 cs_log_dbg(D_DVBAPI, "Demuxer %d ignore ecmpid %d %04X@%06X:%04X:%04X (no matching reader)", demux_index, n, demux[demux_index].ECMpids[n].CAID,
2583 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, demux[demux_index].ECMpids[n].CHID);
2584 demux[demux_index].ECMpids[n].status = -1;
2585 continue; // evaluate next ecmpid
2586 }
2587 else
2588 {
2589 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
2590 {
2591 if(sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid)
2592 {
2593 if((cfg.dvbapi_sidtabs.no & ((SIDTABBITS)1 << nr)) && (chk_srvid_match(er, sidtab)))
2594 {
2595 demux[demux_index].ECMpids[n].status = -1; //ignore
2596 cs_log_dbg(D_DVBAPI, "Demuxer %d ignore ecmpid %d %04X@%06X:%04X (service %s pos %d)", demux_index,
2597 n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID,
2598 demux[demux_index].ECMpids[n].ECM_PID, sidtab->label, nr);
2599 continue; // evaluate next ecmpid
2600 }
2601 if((cfg.dvbapi_sidtabs.ok & ((SIDTABBITS)1 << nr)) && (chk_srvid_match(er, sidtab)))
2602 {
2603 demux[demux_index].ECMpids[n].status++; //priority
2604 cs_log_dbg(D_DVBAPI, "Demuxer %d prio ecmpid %d %04X@%06X:%04X weight: %d (service %s pos %d)", demux_index,
2605 n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID,
2606 demux[demux_index].ECMpids[n].ECM_PID, demux[demux_index].ECMpids[n].status, sidtab->label,nr);
2607 }
2608 }
2609 }
2610 }
2611
2612 // ecmpids with no matching readers are disabled and matching sidtabbits have now highest status
2613
2614 }
2615 // ecmpid with highest prio from oscam.dvbapi has now highest status
2616
2617 // check all ecmpids and get the highest amount cache-ex and local readers
2618 int32_t max_local_matching_reader = 0, max_cacheex_reader = 0;
2619 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2620 {
2621 int32_t count_matching_cacheex_reader = 0, count_matching_local_reader = 0;
2622
2623 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2624
2625 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
2626 er->prid = demux[demux_index].ECMpids[n].PROVID;
2627 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
2628 er->srvid = demux[demux_index].program_number;
2629 er->client = cur_client();
2630 btun_caid = chk_on_btun(SRVID_MASK, er->client, er);
2631
2632 if(btun_caid)
2633 {
2634 er->caid = btun_caid;
2635 }
2636
2637 for(rdr = first_active_reader; rdr ; rdr = rdr->next)
2638 {
2639 if(matching_reader(er, rdr))
2640 {
2641 if(cacheex_reader(rdr))
2642 {
2643 count_matching_cacheex_reader++;
2644 }
2645 else if(is_localreader(rdr, er))
2646 {
2647 count_matching_local_reader++;
2648 }
2649 }
2650 }
2651
2652 if(max_local_matching_reader < count_matching_local_reader)
2653 {
2654 max_local_matching_reader = count_matching_local_reader;
2655 }
2656 if(max_cacheex_reader < count_matching_cacheex_reader)
2657 {
2658 max_cacheex_reader = count_matching_cacheex_reader;
2659 }
2660 }
2661
2662 if(max_local_matching_reader != 0 || max_cacheex_reader != 0)
2663 {
2664 p_order = demux[demux_index].ECMpidcount*2;
2665
2666 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2667 {
2668 int32_t count_matching_cacheex_reader = 0, count_matching_local_reader = 0;
2669 int32_t localprio = 1, cacheexprio = 1;
2670
2671 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2672
2673 if(cfg.preferlocalcards == 2) // ecmpids with local reader get highest prio
2674 {
2675 localprio = max_cacheex_reader+p_order+1;
2676 }
2677 else if(cfg.preferlocalcards == 1) // ecmpids with cacheex reader get highest prio
2678 {
2679 cacheexprio = max_local_matching_reader+p_order+1;
2680 }
2681
2682 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
2683 er->prid = demux[demux_index].ECMpids[n].PROVID;
2684 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
2685 er->srvid = demux[demux_index].program_number;
2686 er->client = cur_client();
2687 btun_caid = chk_on_btun(SRVID_MASK, er->client, er);
2688
2689 if(btun_caid)
2690 {
2691 er->caid = btun_caid;
2692 }
2693 int32_t oldstatus = demux[demux_index].ECMpids[n].status;
2694 int32_t anyreader = 0;
2695 for(rdr = first_active_reader; rdr ; rdr = rdr->next)
2696 {
2697 if(matching_reader(er, rdr))
2698 {
2699 if(cfg.preferlocalcards == 0)
2700 {
2701 if(!matching_done) {demux[demux_index].ECMpids[n].status++;}
2702 anyreader++;
2703 continue;
2704 }
2705 if(cacheex_reader(rdr))
2706 {
2707 demux[demux_index].ECMpids[n].status += cacheexprio;
2708 count_matching_cacheex_reader++;
2709 cacheexprio=1;
2710 }
2711 if(is_localreader(rdr, er))
2712 {
2713 demux[demux_index].ECMpids[n].status += localprio;
2714 count_matching_local_reader++;
2715 localprio=1;
2716 }
2717 }
2718 }
2719
2720 if(oldstatus != demux[demux_index].ECMpids[n].status)
2721 {
2722 if(anyreader)
2723 {
2724 cs_log_dbg(D_DVBAPI, "Demuxer %d prio ecmpid %d %04X@%06X:%04X:%04X weight: %d (%d readers)", demux_index, n, demux[demux_index].ECMpids[n].CAID,
2725 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, demux[demux_index].ECMpids[n].CHID, demux[demux_index].ECMpids[n].status, anyreader);
2726 }
2727 else
2728 {
2729 cs_log_dbg(D_DVBAPI, "Demuxer %d prio ecmpid %d %04X@%06X:%04X:%04X weight: %d (%d local and %d cacheex readers)", demux_index, n, demux[demux_index].ECMpids[n].CAID,
2730 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, demux[demux_index].ECMpids[n].CHID, demux[demux_index].ECMpids[n].status,
2731 count_matching_local_reader, count_matching_cacheex_reader);
2732 }
2733 }
2734 }
2735 }
2736
2737 struct s_channel_cache *c = NULL;
2738
2739 for(n = 0; n < demux[demux_index].ECMpidcount && matching_done == 0; n++)
2740 {
2741 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2742
2743 c = dvbapi_find_channel_cache(demux_index, n, 0); // find exact channel match
2744 if(c != NULL)
2745 {
2746 found = n;
2747 cache = 2; //found cache entry with higher priority
2748 demux[demux_index].ECMpids[n].status++; // prioritize CAIDs which already decoded same caid:provid:srvid
2749 if(c->chid < 0x10000) { demux[demux_index].ECMpids[n].CHID = c->chid; } // if chid registered in cache -> use it!
2750 cs_log_dbg(D_DVBAPI, "Demuxer %d prio ecmpid %d %04X@%06X:%04X weight: %d (found caid/provid/srvid in cache)", demux_index, n,
2751 demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, demux[demux_index].ECMpids[n].status);
2752 break;
2753 }
2754 }
2755
2756 if(found == -1)
2757 {
2758 // prioritize CAIDs which already decoded same caid:provid
2759 for(n = 0; n < demux[demux_index].ECMpidcount && matching_done == 0; n++)
2760 {
2761 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2762
2763 c = dvbapi_find_channel_cache(demux_index, n, 1);
2764 if(c != NULL)
2765 {
2766 cache = 1; //found cache entry
2767 demux[demux_index].ECMpids[n].status++;
2768 cs_log_dbg(D_DVBAPI, "Demuxer %d prio ecmpid %d %04X@%06X:%04X weight: %d (found caid/provid in cache)", demux_index, n,
2769 demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, demux[demux_index].ECMpids[n].status);
2770 }
2771 }
2772 }
2773
2774 int32_t max_status = 0;
2775 int32_t highest_priopid = -1;
2776
2777 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2778 {
2779 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2780
2781 if(demux[demux_index].ECMpids[n].status > max_status) // find highest prio pid
2782 {
2783 max_status = demux[demux_index].ECMpids[n].status;
2784 highest_priopid = n;
2785 }
2786 if(!USE_OPENXCAS) // openxcas doesnt use prio and non-prio run: all are equal!
2787 {
2788 if(demux[demux_index].ECMpids[n].status == 0) { demux[demux_index].ECMpids[n].checked = 2; } // set pids with no status to no prio run
2789 }
2790 }
2791
2792 demux[demux_index].max_status = max_status; // register maxstatus
2793 if(highest_priopid != -1 && found == highest_priopid && cache == 2) // Found entry in channelcache that is valid and has exact match on srvid
2794 {
2795 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2796 {
2797 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2798
2799 if(n != found)
2800 {
2801 // disable non matching pid
2802 demux[demux_index].ECMpids[n].status = -1;
2803 }
2804 else
2805 {
2806 demux[demux_index].ECMpids[n].status = 1;
2807 }
2808 }
2809 demux[demux_index].max_emm_filter = maxfilter - 1;
2810 demux[demux_index].max_status = 1;
2811 cs_log("Demuxer %d found channel in cache and matching prio -> start descrambling ecmpid %d ", demux_index, found);
2812 }
2813
2814 NULLFREE(er);
2815
2816 cs_ftime(&end);
2817 int64_t gone = comp_timeb(&end, &start);
2818 cs_log_dbg(D_DVBAPI, "Demuxer %d sorting the ecmpids took %"PRId64" ms", demux_index, gone);
2819 return;
2820}
2821
2822void dvbapi_parse_descriptor(int32_t demux_id, uint32_t info_length, unsigned char *buffer, uint8_t* is_audio)
2823{
2824 // int32_t ca_pmt_cmd_id = buffer[i + 5];
2825 uint32_t descriptor_length = 0;
2826 uint32_t j, u, k;
2827 uint8_t skip_border = cfg.dvbapi_boxtype == BOXTYPE_SAMYGO ? 0x05 : 0x02; // skip input values <0x05 on samygo
2828
2829 static const char format_identifiers_audio[10][5] =
2830 {
2831 "AC-3", "BSSD", "dmat", "DTS1", "DTS2",
2832 "DTS3", "EAC3", "HDMV", "mlpa", "Opus",
2833 };
2834
2835 if(info_length < 1)
2836 { return; }
2837
2838 if((buffer[0] < skip_border) && info_length > 0) // skip input values like 0x00 and 0x01
2839 {
2840 buffer++;
2841 info_length--;
2842 }
2843
2844 for(j = 0; j + 1 < info_length; j += descriptor_length + 2)
2845 {
2846 descriptor_length = buffer[j + 1];
2847
2848 if(is_audio)
2849 {
2850 if(buffer[j] == 0x6A || buffer[j] == 0x73 || buffer[j] == 0x81)
2851 {
2852 *is_audio = 1;
2853 }
2854 else if(buffer[j] == 0x05 && descriptor_length >= 4)
2855 {
2856 for(k = 0; k < 10; k++)
2857 {
2858 if(memcmp(buffer + j + 2, format_identifiers_audio[k], 4) == 0)
2859 {
2860 *is_audio = 1;
2861 break;
2862 }
2863 }
2864 }
2865 }
2866
2867 if(buffer[j] == 0x81 && descriptor_length == 8) // private descriptor of length 8, assume enigma/tvh
2868 {
2869 demux[demux_id].enigma_namespace = b2i(4, buffer + j + 2);
2870 demux[demux_id].tsid = b2i(2, buffer + j + 6);
2871 demux[demux_id].onid = b2i(2, buffer + j + 8);
2872 cs_log_dbg(D_DVBAPI, "Demuxer %d found pmt type: %02x length: %d (assuming enigma private descriptor: namespace %04x tsid %02x onid %02x)", demux_id,
2873 buffer[j], descriptor_length, demux[demux_id].enigma_namespace, demux[demux_id].tsid, demux[demux_id].onid);
2874 }
2875 else if (descriptor_length !=0)
2876 {
2877 cs_log_dbg(D_TRACE, "Demuxer %d found pmt type: %02x length: %d", demux_id, buffer[j], descriptor_length);
2878 }
2879
2880 if(buffer[j] != 0x09) { continue; }
2881
2882 if(demux[demux_id].ECMpidcount >= ECM_PIDS) { break; }
2883
2884 int32_t descriptor_ca_system_id = b2i(2, buffer + j + 2);
2885 int32_t descriptor_ca_pid = b2i(2, buffer + j + 4)&0x1FFF;
2886 int32_t descriptor_ca_provider = 0;
2887 char txt[40]; // room for PBM: 8 byte pbm and DATE: date
2888 memset(txt, 0x00, sizeof(txt));
2889
2890 if(descriptor_ca_system_id >> 8 == 0x01)
2891 {
2892 for(u = 2; u < descriptor_length; u += 15)
2893 {
2894 descriptor_ca_pid = b2i(2, buffer + j + u + 2)&0x1FFF;
2895 descriptor_ca_provider = b2i(2, buffer + j + u + 4);
2896 int8_t year = buffer[j + u + 15] >> 1;
2897 int8_t month = (((buffer[j + u + 15]&0x01) << 3) | (buffer[j + u + 16] >> 5));
2898 int8_t day = buffer[j + u + 16]&0x1F;
2899 snprintf(txt, sizeof(txt), "PBM: ");
2900 cs_hexdump(0, buffer + j + u + 7, 8, txt+5, (2*8)+1); // hexdump 8 byte pbm
2901 snprintf(txt+20, sizeof(txt)-20, " DATE: %d-%d-%d", day, month, year+1990);
2902 dvbapi_add_ecmpid(demux_id, descriptor_ca_system_id, descriptor_ca_pid, descriptor_ca_provider, txt);
2903 }
2904 }
2905 else
2906 {
2907 if(caid_is_viaccess(descriptor_ca_system_id) && descriptor_length == 0x0F && buffer[j + 12] == 0x14)
2908 { descriptor_ca_provider = b2i(3, buffer + j + 14) &0xFFFFF0; }
2909
2910 if(caid_is_nagra(descriptor_ca_system_id) && descriptor_length == 0x07)
2911 { descriptor_ca_provider = b2i(2, buffer + j + 7); }
2912
2913 if((descriptor_ca_system_id >> 8 == 0x4A || descriptor_ca_system_id == 0x2710) && descriptor_length > 0x04 )
2914 { descriptor_ca_provider = buffer[j + 6]; }
2915
2916 dvbapi_add_ecmpid(demux_id, descriptor_ca_system_id, descriptor_ca_pid, descriptor_ca_provider, txt);
2917
2918 }
2919 }
2920
2921 // Apply mapping:
2922 if(dvbapi_priority)
2923 {
2924 struct s_dvbapi_priority *mapentry;
2925 for(j = 0; (int32_t)j < demux[demux_id].ECMpidcount; j++)
2926 {
2927 mapentry = dvbapi_check_prio_match(demux_id, j, 'm');
2928 if(mapentry)
2929 {
2930 cs_log_dbg(D_DVBAPI, "Demuxer %d mapping ecmpid %d from %04X@%06X to %04X@%06X", demux_id, j,
2931 demux[demux_id].ECMpids[j].CAID, demux[demux_id].ECMpids[j].PROVID,
2932 mapentry->mapcaid, mapentry->mapprovid);
2933 demux[demux_id].ECMpids[j].CAID = mapentry->mapcaid;
2934 demux[demux_id].ECMpids[j].PROVID = mapentry->mapprovid;
2935 }
2936 }
2937 }
2938}
2939
2940void request_cw(struct s_client *client, ECM_REQUEST *er, int32_t demux_id, uint8_t delayed_ecm_check)
2941{
2942 if(!er)
2943 {
2944 return;
2945 }
2946
2947
2948 int32_t filternum = dvbapi_set_section_filter(demux_id, er, -1); // set ecm filter to odd -> even and visaversa
2949 if(filternum < 0)
2950 {
2951 cs_log_dbg(D_DVBAPI, "Demuxer %d not requesting cw -> ecm filter was killed!", demux_id);
2952 NULLFREE(er);
2953 return;
2954 }
2955
2956 if(!delayed_ecm_check) // no delayed ecm check for this filter
2957 {
2958 memset(demux[demux_id].demux_fd[filternum].lastecmd5, 0, CS_ECMSTORESIZE); // no ecm delay check: zero it!
2959 }
2960 else
2961 {
2962 unsigned char md5tmp[MD5_DIGEST_LENGTH];
2963 MD5(er->ecm, er->ecmlen, md5tmp);
2964 if(!memcmp(demux[demux_id].demux_fd[filternum].prevecmd5, md5tmp, CS_ECMSTORESIZE))
2965 {
2966 if(demux[demux_id].demux_fd[filternum].prevresult < E_NOTFOUND)
2967 {
2968 cs_log_dbg(D_DVBAPI, "Demuxer %d not requesting same ecm again! -> SKIP!", demux_id);
2969 NULLFREE(er);
2970 return;
2971 }
2972 else
2973 {
2974 cs_log_dbg(D_DVBAPI, "Demuxer %d requesting same ecm again (previous result was not found!)", demux_id);
2975 }
2976 }
2977 else if(!memcmp(demux[demux_id].demux_fd[filternum].lastecmd5, md5tmp, CS_ECMSTORESIZE))
2978 {
2979 if(demux[demux_id].demux_fd[filternum].lastresult < E_NOTFOUND)
2980 {
2981 cs_log_dbg(D_DVBAPI, "Demuxer %d not requesting same ecm again! -> SKIP!", demux_id);
2982 NULLFREE(er);
2983 return;
2984 }
2985 else
2986 {
2987 cs_log_dbg(D_DVBAPI, "Demuxer %d requesting same ecm again (previous result was not found!)", demux_id);
2988 }
2989 }
2990 memcpy(demux[demux_id].demux_fd[filternum].prevecmd5, demux[demux_id].demux_fd[filternum].lastecmd5, CS_ECMSTORESIZE);
2991 demux[demux_id].demux_fd[filternum].prevresult = demux[demux_id].demux_fd[filternum].lastresult;
2992 memcpy(demux[demux_id].demux_fd[filternum].lastecmd5, md5tmp, CS_ECMSTORESIZE);
2993 demux[demux_id].demux_fd[filternum].lastresult = 0xFF;
2994 }
2995
2996 cs_log_dbg(D_DVBAPI, "Demuxer %d get controlword!", demux_id);
2997 get_cw(client, er);
2998
2999#ifdef WITH_DEBUG
3000 char buf[ECM_FMT_LEN];
3001 format_ecm(er, buf, ECM_FMT_LEN);
3002 cs_log_dbg(D_DVBAPI, "Demuxer %d request controlword for ecm %s", demux_id, buf);
3003#endif
3004}
3005
3006void dvbapi_try_next_caid(int32_t demux_id, int8_t checked)
3007{
3008
3009 int32_t n, j, found = -1, started = 0;
3010
3011 int32_t status = demux[demux_id].max_status;
3012
3013 for(j = status; j >= 0; j--) // largest status first!
3014 {
3015
3016 for(n = 0; n < demux[demux_id].ECMpidcount; n++)
3017 {
3018 //cs_log_dbg(D_DVBAPI,"Demuxer %d PID %d checked = %d status = %d (searching for pid with status = %d)", demux_id, n,
3019 // demux[demux_id].ECMpids[n].checked, demux[demux_id].ECMpids[n].status, j);
3020 if(demux[demux_id].ECMpids[n].checked == checked && demux[demux_id].ECMpids[n].status == j)
3021 {
3022 found = n;
3023
3024 openxcas_set_provid(demux[demux_id].ECMpids[found].PROVID);
3025 openxcas_set_caid(demux[demux_id].ECMpids[found].CAID);
3026 openxcas_set_ecm_pid(demux[demux_id].ECMpids[found].ECM_PID);
3027
3028 // fixup for cas that need emm first!
3029 if(caid_is_irdeto(demux[demux_id].ECMpids[found].CAID)) { demux[demux_id].emmstart.time = 0; }
3030 started = dvbapi_start_descrambling(demux_id, found, checked);
3031 if(cfg.dvbapi_requestmode == 0 && started == 1) { return; } // in requestmode 0 we only start 1 ecm request at the time
3032 }
3033 }
3034 }
3035
3036 if(found == -1 && demux[demux_id].pidindex == -1)
3037 {
3038 cs_log("Demuxer %d no suitable readers found that can be used for decoding!", demux_id);
3039 return;
3040 }
3041}
3042
3043static void getDemuxOptions(int32_t demux_id, unsigned char *buffer, uint32_t *ca_mask, uint16_t *demux_index, uint16_t *adapter_index, uint16_t *pmtpid)
3044{
3045 *ca_mask = 0x01, *demux_index = 0x00, *adapter_index = 0x00, *pmtpid = 0x00;
3046
3047 if(buffer[17] == 0x82 && buffer[18] == 0x02)
3048 {
3049 // enigma2
3050 *ca_mask = buffer[19];
3051 uint32_t demuxid = buffer[20];
3052 if (demuxid == 0xff) demuxid = 0; // tryfix prismcube (0xff -> "demux-1" = error! )
3053 *demux_index = demuxid;
3054 if (buffer[21]==0x84 && buffer[22]==0x02) *pmtpid = b2i(2, buffer+23);
3055 if (buffer[25]==0x83 && buffer[26]==0x01) *adapter_index=buffer[27]; // from code cahandler.cpp 0x83 index of adapter
3056 }
3057
3058 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX_PMT)
3059 {
3060 *ca_mask = demux_id + 1;
3061 *demux_index = demux_id;
3062 }
3063
3064 if(cfg.dvbapi_boxtype == BOXTYPE_QBOXHD && buffer[17] == 0x82 && buffer[18] == 0x03)
3065 {
3066 // ca_mask = buffer[19]; // with STONE 1.0.4 always 0x01
3067 *demux_index = buffer[20]; // with STONE 1.0.4 always 0x00
3068 *adapter_index = buffer[21]; // with STONE 1.0.4 adapter index can be 0,1,2
3069 *ca_mask = (1 << *adapter_index); // use adapter_index as ca_mask (used as index for ca_fd[] array)
3070 }
3071
3072 if((cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX || cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
3073 && buffer[7] == 0x82 && buffer[8] == 0x02)
3074 {
3075 *demux_index = buffer[9]; // it is always 0 but you never know
3076 *adapter_index = buffer[10]; // adapter index can be 0,1,2
3077 *ca_mask = (1 << *adapter_index); // use adapter_index as ca_mask (used as index for ca_fd[] array)
3078 }
3079}
3080
3081static void dvbapi_capmt_notify(struct demux_s *dmx)
3082{
3083 struct s_client *cl;
3084 for(cl = first_client->next; cl ; cl = cl->next)
3085 {
3086 if((cl->typ == 'p' || cl->typ == 'r') && cl->reader && cl->reader->ph.c_capmt)
3087 {
3088 struct demux_s *curdemux;
3089 if(cs_malloc(&curdemux, sizeof(struct demux_s)))
3090 {
3091 memcpy(curdemux, dmx, sizeof(struct demux_s));
3092 add_job(cl, ACTION_READER_CAPMT_NOTIFY, curdemux, sizeof(struct demux_s));
3093 }
3094 }
3095 }
3096}
3097
3098int32_t dvbapi_parse_capmt(unsigned char *buffer, uint32_t length, int32_t connfd, char *pmtfile, int8_t is_real_pmt, uint16_t existing_demux_id, uint16_t client_proto_version)
3099{
3100 uint32_t i = 0, start_descrambling = 0;
3101 int32_t j = 0;
3102 int32_t demux_id = -1;
3103 uint16_t demux_index, adapter_index, pmtpid;
3104 uint32_t ca_mask;
3105 uint32_t program_number, program_info_length;
3106 uint8_t program_info_start = is_real_pmt ? 12 : 6;
3107
3108 if(!is_real_pmt)
3109 {
3110
3111#define LIST_MORE 0x00 //*CA application should append a 'MORE' CAPMT object to the list and start receiving the next object
3112#define LIST_FIRST 0x01 //*CA application should clear the list when a 'FIRST' CAPMT object is received, and start receiving the next object
3113#define LIST_LAST 0x02 //*CA application should append a 'LAST' CAPMT object to the list and start working with the list
3114#define LIST_ONLY 0x03 //*CA application should clear the list when an 'ONLY' CAPMT object is received, and start working with the object
3115#define LIST_ADD 0x04 //*CA application should append an 'ADD' CAPMT object to the current list and start working with the updated list
3116#define LIST_UPDATE 0x05 //*CA application should replace an entry in the list with an 'UPDATE' CAPMT object, and start working with the updated list
3117
3118#if defined WITH_COOLAPI || defined WITH_COOLAPI2
3119 int32_t ca_pmt_list_management = LIST_ONLY;
3120#else
3121 int32_t ca_pmt_list_management = buffer[0];
3122#endif
3123 program_number = b2i(2, buffer + 1);
3124 program_info_length = b2i(2, buffer + 4) &0xFFF;
3125
3126 cs_log_dump_dbg(D_DVBAPI, buffer, length, "capmt:");
3127 cs_log_dbg(D_DVBAPI, "Receiver sends PMT command %d for channel %04X", ca_pmt_list_management, program_number);
3128
3129 if(!pmt_stopmarking && (ca_pmt_list_management == LIST_FIRST || ca_pmt_list_management == LIST_ONLY))
3130 {
3131 for(i = 0; i < MAX_DEMUX; i++)
3132 {
3133 if(demux[i].program_number == 0) { continue; } // skip empty demuxers
3134 if(demux[i].socket_fd != connfd) { continue; } // skip demuxers belonging to other ca pmt connection
3135 if((demux[i].socket_fd == -1) && (pmtfile && strcmp(demux[i].pmt_file, pmtfile) != 0)) { continue; } // skip demuxers handled by other pmt files
3136 demux[i].stopdescramble = 1; // Mark for deletion if not used again by following pmt objects.
3137 cs_log_dbg(D_DVBAPI, "Marked demuxer %d/%d (srvid = %04X fd = %d) to stop decoding", i, MAX_DEMUX, demux[i].program_number, connfd);
3138 }
3139 pmt_stopmarking = 1; // only stop demuxing for first pmt record
3140 }
3141
3142 getDemuxOptions(i, buffer, &ca_mask, &demux_index, &adapter_index, &pmtpid);
3143 cs_log_dbg(D_DVBAPI,"Receiver wants to demux srvid %04X on adapter %04X camask %04X index %04X pmtpid %04X",
3144 program_number, adapter_index, ca_mask, demux_index, pmtpid);
3145
3146 for(i = 0; i < MAX_DEMUX; i++) // search current demuxers for running the same program as the one we received in this PMT object
3147 {
3148 if(demux[i].program_number == 0) { continue; }
3149 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX_PMT) demux_index = i; // fixup for ipbox
3150
3151 bool full_check = 1, matched = 0;
3152 if (config_enabled(WITH_COOLAPI) || config_enabled(WITH_COOLAPI2) || cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
3153 full_check = 0;
3154
3155 if (full_check)
3156 matched = (connfd > 0 && demux[i].socket_fd == connfd) && demux[i].program_number == program_number;
3157 else
3158 matched = connfd > 0 && demux[i].program_number == program_number;
3159
3160 if(matched)
3161 {
3162 if (full_check) {
3163 if (demux[i].adapter_index != adapter_index) continue; // perhaps next demuxer matches?
3164 if (demux[i].ca_mask != ca_mask) continue; // perhaps next demuxer matches?
3165 if (demux[i].demux_index != demux_index) continue; // perhaps next demuxer matches?
3166 }
3167 if(ca_pmt_list_management == LIST_UPDATE){
3168 cs_log("Demuxer %d PMT update for decoding of SRVID %04X! ", i, program_number);
3169 }
3170
3171 demux_id = i;
3172
3173 cs_log("Demuxer %d continue decoding of SRVID %04X", i, demux[i].program_number);
3174
3175 openxcas_set_sid(program_number);
3176
3177 demux[i].stopdescramble = 0; // dont stop current demuxer!
3178 break; // no need to explore other demuxers since we have a found!
3179 }
3180 }
3181
3182 // start using the new list
3183 if(ca_pmt_list_management != LIST_FIRST && ca_pmt_list_management != LIST_MORE)
3184 {
3185 for(j = 0; j < MAX_DEMUX; j++)
3186 {
3187 if(demux[j].program_number == 0) { continue; }
3188 if(demux[j].stopdescramble == 1) { dvbapi_stop_descrambling(j); }// Stop descrambling and remove all demuxer entries not in new PMT.
3189 }
3190 start_descrambling = 1; // flag that demuxer descrambling is to be executed!
3191 pmt_stopmarking = 0; // flag that demuxers may be marked for stop decoding again
3192 }
3193
3194 if(demux_id == -1)
3195 {
3196 for(demux_id = 0; demux_id < MAX_DEMUX; demux_id++)
3197 {
3198 if(demux[demux_id].program_number == 0)
3199 {
3200 demux[demux_id].program_number = program_number; // do this early since some prio items use them!
3201 demux[demux_id].enigma_namespace = 0;
3202 demux[demux_id].tsid = 0;
3203 demux[demux_id].onid = 0;
3204 demux[demux_id].pmtpid = pmtpid;
3205 demux[demux_id].socket_fd = connfd;
3206 demux[demux_id].adapter_index = adapter_index;
3207 demux[demux_id].client_proto_version = client_proto_version;
3208 demux[demux_id].sdt_filter = -1;
3209
3210 if(pmtfile)
3211 {
3212 cs_strncpy(demux[demux_id].pmt_file, pmtfile, sizeof(demux[demux_id].pmt_file));
3213 }
3214
3215 // free demuxer found, start pat/pmt filter for this new demuxer
3216 if(pmtpid)
3217 {
3218 dvbapi_start_pmt_filter(demux_id, pmtpid);
3219 }
3220 else
3221 {
3222 dvbapi_start_pat_filter(demux_id);
3223 }
3224 break;
3225 }
3226 }
3227 }
3228
3229 if(demux_id >= MAX_DEMUX)
3230 {
3231 cs_log("ERROR: No free id (MAX_DEMUX)");
3232 return -1;
3233 }
3234
3235 if(demux[demux_id].running == 0) demux[demux_id].ECMpidcount = 0; // reset number of ecmpids only if it was not running!
3236 }
3237 else // is_real_pmt
3238 {
3239 demux_id = existing_demux_id;
3240
3241 dvbapi_stop_filter(demux_id, TYPE_PMT);
3242
3243 program_number = b2i(2, buffer + 3);
3244 program_info_length = b2i(2, buffer + 10) &0xFFF;
3245
3246 cs_log_dump_dbg(D_DVBAPI, buffer, length, "pmt:");
3247 pmtpid = demux[demux_id].pmtpid;
3248 }
3249
3250 for(j = 0; j < demux[demux_id].ECMpidcount; j++) // cleanout demuxer from possible stale info
3251 {
3252 demux[demux_id].ECMpids[j].streams = 0; // reset streams of each ecmpid!
3253 }
3254 demux[demux_id].STREAMpidcount = 0; // reset number of streams
3255
3256 if(program_info_length > 1 && program_info_length < length)
3257 {
3258 dvbapi_parse_descriptor(demux_id, program_info_length - 1, buffer + program_info_start, NULL);
3259 }
3260
3261 uint32_t es_info_length = 0, vpid = 0;
3262 struct s_dvbapi_priority *addentry;
3263
3264 for(i = program_info_length + program_info_start; i + 4 < length; i += es_info_length + 5)
3265 {
3266 uint8_t stream_type = buffer[i];
3267 uint16_t elementary_pid = b2i(2, buffer + i + 1)&0x1FFF;
3268 uint8_t is_audio = 0;
3269 es_info_length = b2i(2, buffer + i +3)&0x0FFF;
3270
3271 if(demux[demux_id].STREAMpidcount >= ECM_PIDS)
3272 {
3273 break;
3274 }
3275
3276 demux[demux_id].STREAMpids[demux[demux_id].STREAMpidcount] = elementary_pid;
3277 demux[demux_id].STREAMpidsType[demux[demux_id].STREAMpidcount] = buffer[i];
3278 demux[demux_id].STREAMpidcount++;
3279
3280 cs_log("Demuxer %d stream %s(type: %02x pid: %04x length: %d)", demux_id, get_streamtxt(stream_type), stream_type, elementary_pid, es_info_length);
3281
3282 // find and register videopid
3283 if(!vpid &&
3284 (stream_type == 0x01 || stream_type == 0x02 || stream_type == 0x10 || stream_type == 0x1B
3285 || stream_type == 0x24 || stream_type == 0x42 || stream_type == 0xD1 || stream_type == 0xEA))
3286 {
3287 vpid = elementary_pid;
3288 }
3289
3290 if(es_info_length != 0 && es_info_length < length)
3291 {
3292 dvbapi_parse_descriptor(demux_id, es_info_length, buffer + i + 5, &is_audio);
3293
3294 if((stream_type == 0x06 || stream_type == 0x80 || stream_type == 0x82) && is_audio)
3295 {
3296 demux[demux_id].STREAMpidsType[demux[demux_id].STREAMpidcount-1] = 0x03;
3297 stream_type = 0x03;
3298 }
3299 else if(!vpid && stream_type == 0x80 && !is_audio)
3300 {
3301 vpid = elementary_pid;
3302 }
3303 }
3304 else
3305 {
3306 for(addentry = dvbapi_priority; addentry != NULL; addentry = addentry->next)
3307 {
3308 if(addentry->type != 'a'
3309 || (addentry->ecmpid && pmtpid && addentry->ecmpid != pmtpid) // ecmpid is misused to hold pmtpid in case of A: rule
3310 || (addentry->ecmpid && !pmtpid && addentry->ecmpid != vpid) // some receivers dont forward pmtpid, use vpid instead
3311 || (addentry->srvid != demux[demux_id].program_number))
3312 { continue; }
3313 cs_log_dbg(D_DVBAPI, "Demuxer %d fake ecmpid %04X@%06X:%04x for unencrypted stream on srvid %04X", demux_id, addentry->mapcaid, addentry->mapprovid,
3314 addentry->mapecmpid, demux[demux_id].program_number);
3315 dvbapi_add_ecmpid(demux_id, addentry->mapcaid, addentry->mapecmpid, addentry->mapprovid, " (fake ecmpid)");
3316 break;
3317 }
3318 }
3319 }
3320
3321 if(!is_real_pmt)
3322 {
3323 cs_log("Demuxer %d found %d ECMpids and %d STREAMpids in caPMT", demux_id, demux[demux_id].ECMpidcount, demux[demux_id].STREAMpidcount);
3324
3325 getDemuxOptions(demux_id, buffer, &ca_mask, &demux_index, &adapter_index, &pmtpid);
3326 demux[demux_id].adapter_index = adapter_index;
3327 demux[demux_id].ca_mask = ca_mask;
3328 demux[demux_id].rdr = NULL;
3329 demux[demux_id].demux_index = demux_index;
3330 demux[demux_id].socket_fd = connfd;
3331 demux[demux_id].client_proto_version = client_proto_version;
3332
3333 if(demux[demux_id].STREAMpidcount == 0) // encrypted PMT
3334 {
3335 demux[demux_id].STREAMpids[demux[demux_id].STREAMpidcount] = pmtpid;
3336 demux[demux_id].STREAMpidsType[demux[demux_id].STREAMpidcount] = 0x01;
3337 demux[demux_id].STREAMpidcount++;
3338 vpid = pmtpid;
3339 }
3340 }
3341 else
3342 {
3343 cs_log("Demuxer %d found %d ECMpids and %d STREAMpids in PMT", demux_id, demux[demux_id].ECMpidcount, demux[demux_id].STREAMpidcount);
3344
3345 ca_mask = demux[demux_id].ca_mask;
3346 demux_index = demux[demux_id].demux_index;
3347 adapter_index = demux[demux_id].adapter_index;
3348 connfd = demux[demux_id].socket_fd;
3349 }
3350
3351 for(j = 0; j < demux[demux_id].ECMpidcount; j++)
3352 {
3353 demux[demux_id].ECMpids[j].VPID = vpid; // register found vpid on all ecmpids of this demuxer
3354 }
3355
3356 char channame[CS_SERVICENAME_SIZE];
3357 get_servicename(dvbapi_client, demux[demux_id].program_number, demux[demux_id].ECMpidcount > 0 ? demux[demux_id].ECMpids[0].PROVID : NO_PROVID_VALUE, demux[demux_id].ECMpidcount > 0 ? demux[demux_id].ECMpids[0].CAID : NO_CAID_VALUE, channame, sizeof(channame));
3358 cs_log("Demuxer %d serving srvid %04X (%s) on adapter %04X camask %04X index %04X pmtpid %04X", demux_id, demux[demux_id].program_number, channame, adapter_index, ca_mask, demux_index, pmtpid);
3359 demux[demux_id].stopdescramble = 0; // remove deletion mark!
3360
3361 // remove from unassoc_fd when necessary
3362 for (j = 0; j < MAX_DEMUX; j++)
3363 if (unassoc_fd[j] == connfd)
3364 unassoc_fd[j] = 0;
3365
3366 dvbapi_capmt_notify(&demux[demux_id]);
3367
3368 struct s_dvbapi_priority *xtraentry;
3369 int32_t k, l, m, xtra_demux_id;
3370
3371 for(xtraentry = dvbapi_priority; xtraentry != NULL; xtraentry = xtraentry->next)
3372 {
3373 if(xtraentry->type != 'x') { continue; }
3374
3375 for(j = 0; j <= demux[demux_id].ECMpidcount; ++j)
3376 {
3377 if((xtraentry->caid && xtraentry->caid != demux[demux_id].ECMpids[j].CAID)
3378 || (xtraentry->provid && xtraentry->provid != demux[demux_id].ECMpids[j].PROVID)
3379 || (xtraentry->ecmpid && xtraentry->ecmpid != demux[demux_id].ECMpids[j].ECM_PID)
3380 || (xtraentry->srvid && xtraentry->srvid != demux[demux_id].program_number))
3381 { continue; }
3382
3383 cs_log("Mapping ecmpid %04X@%06X:%04X:%04X to xtra demuxer/ca-devices", xtraentry->caid, xtraentry->provid, xtraentry->ecmpid, xtraentry->srvid);
3384
3385 for(xtra_demux_id = 0; xtra_demux_id < MAX_DEMUX && demux[xtra_demux_id].program_number > 0; xtra_demux_id++)
3386 { ; }
3387
3388 if(xtra_demux_id >= MAX_DEMUX)
3389 {
3390 cs_log("Found no free demux device for xtra streams.");
3391 continue;
3392 }
3393 // copy to new demuxer
3394 if(!is_real_pmt)
3395 {
3396 getDemuxOptions(demux_id, buffer, &ca_mask, &demux_index, &adapter_index, &pmtpid);
3397 }
3398 demux[xtra_demux_id].ECMpids[0] = demux[demux_id].ECMpids[j];
3399 demux[xtra_demux_id].ECMpidcount = 1;
3400 demux[xtra_demux_id].STREAMpidcount = 0;
3401 demux[xtra_demux_id].program_number = demux[demux_id].program_number;
3402 demux[xtra_demux_id].pmtpid = demux[demux_id].pmtpid;
3403 demux[xtra_demux_id].demux_index = demux_index;
3404 demux[xtra_demux_id].adapter_index = adapter_index;
3405 demux[xtra_demux_id].ca_mask = ca_mask;
3406 demux[xtra_demux_id].socket_fd = connfd;
3407 demux[xtra_demux_id].stopdescramble = 0; // remove deletion mark!
3408 demux[xtra_demux_id].rdr = NULL;
3409 demux[xtra_demux_id].curindex = -1;
3410
3411 // add streams to xtra demux
3412 for(k = 0; k < demux[demux_id].STREAMpidcount; ++k)
3413 {
3414 if(!demux[demux_id].ECMpids[j].streams || (demux[demux_id].ECMpids[j].streams & (1 << k)))
3415 {
3416 demux[xtra_demux_id].ECMpids[0].streams |= (1 << demux[xtra_demux_id].STREAMpidcount);
3417 demux[xtra_demux_id].STREAMpids[demux[xtra_demux_id].STREAMpidcount] = demux[demux_id].STREAMpids[k];
3418 demux[xtra_demux_id].STREAMpidsType[demux[xtra_demux_id].STREAMpidcount] = demux[demux_id].STREAMpidsType[k];
3419 ++demux[xtra_demux_id].STREAMpidcount;
3420
3421 // shift stream associations in normal demux because we will remove the stream entirely
3422 for(l = 0; l < demux[demux_id].ECMpidcount; ++l)
3423 {
3424 for(m = k; m < demux[demux_id].STREAMpidcount - 1; ++m)
3425 {
3426 if(demux[demux_id].ECMpids[l].streams & (1 << (m + 1)))
3427 {
3428 demux[demux_id].ECMpids[l].streams |= (1 << m);
3429 }
3430 else
3431 {
3432 demux[demux_id].ECMpids[l].streams &= ~(1 << m);
3433 }
3434 }
3435 }
3436
3437 // remove stream association from normal demux device
3438 for(l = k; l < demux[demux_id].STREAMpidcount - 1; ++l)
3439 {
3440 demux[demux_id].STREAMpids[l] = demux[demux_id].STREAMpids[l + 1];
3441 demux[demux_id].STREAMpidsType[l] = demux[demux_id].STREAMpidsType[l + 1];
3442 }
3443 --demux[demux_id].STREAMpidcount;
3444 --k;
3445 }
3446 }
3447
3448 // remove ecmpid from normal demuxer
3449 for(k = j; k < demux[demux_id].ECMpidcount; ++k)
3450 {
3451 demux[demux_id].ECMpids[k] = demux[demux_id].ECMpids[k + 1];
3452 }
3453 --demux[demux_id].ECMpidcount;
3454 --j;
3455
3456 if(demux[xtra_demux_id].STREAMpidcount <= 0)
3457 {
3458 cs_log("Found no streams for xtra demuxer. Not starting additional decoding on it.");
3459 demux[xtra_demux_id].program_number = 0;
3460 demux[xtra_demux_id].stopdescramble = 1;
3461 }
3462
3463 if(demux[demux_id].STREAMpidcount < 1)
3464 {
3465 cs_log("Found no streams for normal demuxer. Not starting additional decoding on it.");
3466 }
3467 }
3468 }
3469
3470 if(cfg.dvbapi_au > 0 && demux[demux_id].EMMpidcount == 0) // only do emm setup if au enabled and not running!
3471 {
3472 demux[demux_id].emm_filter = -1; // to register first run emmfilter start
3473 if(demux[demux_id].emmstart.time == 1) // irdeto fetch emm cat direct!
3474 {
3475 cs_ftime(&demux[demux_id].emmstart); // trick to let emm fetching start after 30 seconds to speed up zapping
3476 dvbapi_start_filter(demux_id, demux[demux_id].pidindex, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM); //CAT
3477 }
3478 else { cs_ftime(&demux[demux_id].emmstart); } // for all other caids delayed start!
3479 }
3480
3481 if(start_descrambling)
3482 {
3483 for(j = 0; j < MAX_DEMUX; j++)
3484 {
3485 if(demux[j].program_number == 0) { continue; }
3486 if(demux[j].socket_fd != connfd) { continue; } // skip demuxers belonging to other ca pmt connection
3487 if((demux[j].socket_fd == -1) && (pmtfile && strcmp(demux[j].pmt_file, pmtfile) != 0)) { continue; } // skip demuxers handled by other pmt files
3488
3489 if(demux[j].running && demux_id == j) disable_unused_streampids(j); // disable all streampids not in use anymore
3490
3491 if(demux[j].running == 0 && demux[j].ECMpidcount != 0 ) // only start demuxer if it wasnt running
3492 {
3493 dvbapi_stop_all_emm_sdt_filtering(); // remove all unimportant filtering (there are images with limited amount of filters available!)
3494 cs_log_dbg(D_DVBAPI, "Demuxer %d/%d lets start descrambling (srvid = %04X fd = %d ecmpids = %d)", j, MAX_DEMUX,
3495 demux[j].program_number, connfd, demux[j].ECMpidcount);
3496 demux[j].running = 1; // mark channel as running
3497 openxcas_set_sid(demux[j].program_number);
3498 demux[j].decodingtries = -1;
3499 dvbapi_resort_ecmpids(j);
3500 dvbapi_try_next_caid(j, 0);
3501 cs_sleepms(1);
3502 }
3503 else if(demux[j].ECMpidcount == 0) //fta do logging and part of ecmhandler since there will be no ecms asked!
3504 {
3505 cs_log_dbg(D_DVBAPI, "Demuxer %d/%d no descrambling needed (srvid = %04X fd = %d ecmpids = %d)", j, MAX_DEMUX,
3506 demux[j].program_number, connfd, demux[j].ECMpidcount);
3507 demux[j].running = 0; // reset running flag
3508 demux[demux_id].pidindex = -1; // reset ecmpid used for descrambling
3509 dvbapi_stop_filter(j, TYPE_ECM);
3510 if(cfg.usrfileflag) { cs_statistics(dvbapi_client);} // add to user log previous channel + time on channel
3511 dvbapi_client->last_srvid = demux[demux_id].program_number; // set new channel srvid
3512 dvbapi_client->last_caid = NO_CAID_VALUE; // FTA channels have no caid!
3513 dvbapi_client->last_provid = NO_PROVID_VALUE; // FTA channels have no provid!
3514 dvbapi_client->lastswitch = dvbapi_client->last = time((time_t *)0); // reset idle-Time & last switch
3515 }
3516 }
3517 }
3518 return demux_id;
3519}
3520
3521static uint32_t dvbapi_extract_sdt_string(char *buf, uint32_t buflen, uint8_t* source, uint32_t sourcelen)
3522{
3523 uint32_t i, j, offset = 0;
3524 int8_t iso_mode = -1;
3525 char *tmpbuf;
3526 const unsigned char *ptr_in;
3527 unsigned char *ptr_out;
3528 size_t in_bytes, out_bytes;
3529
3530 if(sourcelen == 0)
3531 {
3532 buf[0] = '\0';
3533 return 1;
3534 }
3535
3536 if(!cs_malloc(&tmpbuf, buflen))
3537 {
3538 return 0;
3539 }
3540
3541 if((sourcelen + 1) > buflen)
3542 { sourcelen = buflen - 1; }
3543
3544 if(sourcelen > 0 && source[0] < 0x20)
3545 {
3546 //ISO-8859
3547 if(source[0] >= 0x01 && source[0] <= 0x0B && source[0] != 0x08)
3548 { offset = 1; iso_mode = 4+source[0]; }
3549
3550 //ISO-8859
3551 else if(source[0] == 0x10 && source[1] == 0x00
3552 && source[2] >= 0x01 && source[2] <= 0x0F && source[2] != 0x0C)
3553 { offset = 3; iso_mode = source[2]; }
3554
3555 //Unicode
3556 else if(source[0] == 0x11)
3557 { offset = 1; iso_mode = -2;}
3558
3559 //missing: 0x12 Korean Character Set KSC5601-1987
3560 //missing: 0x13 Simplified Chinese Character Set GB-2312-1980
3561 //missing: 0x14 Big5 subset of ISO/IEC 10646-1 (Traditional Chinese)
3562
3563 //Unicode as UTF-8
3564 else if(source[0] == 0x15)
3565 { offset = 1; iso_mode = -3;}
3566
3567 //missing: 0x1F Described by encoding_type_id *standard not finished yet*
3568
3569 //Reserved for future use
3570 else
3571 { NULLFREE(tmpbuf); return 0; }
3572 }
3573
3574 if(offset >= sourcelen)
3575 { NULLFREE(tmpbuf); return 0; }
3576
3577 if(iso_mode >= -1)
3578 {
3579 for(i=0, j=0; i<(sourcelen-offset); i++)
3580 {
3581 if(((uint8_t)source[offset+i]) >= 0x80 && ((uint8_t)source[offset+i]) <= 0x9F)
3582 {
3583 continue;
3584 }
3585
3586 tmpbuf[j] = source[offset+i];
3587 j++;
3588 }
3589 tmpbuf[j] = '\0';
3590 }
3591
3592 ptr_in = (const unsigned char *)tmpbuf;
3593 in_bytes = strlen(tmpbuf);
3594 ptr_out = (unsigned char *)buf;
3595 out_bytes = buflen;
3596
3597#ifdef READ_SDT_CHARSETS
3598 if(iso_mode >= -1)
3599 {
3600 memset(buf, 0, buflen);
3601
3602 cs_log_dbg(D_DVBAPI, "sdt-info dbg: iso_mode: %d offset: %u", iso_mode, offset);
3603 cs_log_dump_dbg(D_DVBAPI, (uint8_t*)tmpbuf, in_bytes, "sdt-info dbg: raw string: ");
3604
3605 if(iso_mode == -1)
3606 {
3607 if(ISO6937toUTF8(&ptr_in, &in_bytes, &ptr_out, &out_bytes) == (size_t)(-1))
3608 {
3609 cs_log_dbg(D_DVBAPI, "sdt-info error: ISO6937toUTF8 failed");
3610 NULLFREE(tmpbuf);
3611 return 0;
3612 }
3613 }
3614 else
3615 {
3616 if(ISO8859toUTF8(iso_mode, &ptr_in, &in_bytes, &ptr_out, &out_bytes) == (size_t)(-1))
3617 {
3618 cs_log_dbg(D_DVBAPI, "sdt-info error: ISO8859toUTF8 failed");
3619 NULLFREE(tmpbuf);
3620 return 0;
3621 }
3622 }
3623 }
3624#else
3625 if(iso_mode >= -1)
3626 {
3627 cs_strncpy(buf, tmpbuf, buflen);
3628 cs_log_dbg(D_DVBAPI, "sdt-info warning: your build of oscam does not support iso-to-utf8 conversion, special chars may be corrupted!");
3629 }
3630#endif
3631
3632 else if(iso_mode == -2)
3633 {
3634 memset(buf, 0, buflen);
3635
3636 cs_log_dbg(D_DVBAPI, "sdt-info dbg: iso_mode: %d offset: %u", iso_mode, offset);
3637
3638 if(UnicodetoUTF8(&ptr_in, &in_bytes, &ptr_out, &out_bytes) == (size_t)(-1))
3639 {
3640 cs_log_dbg(D_DVBAPI, "sdt-info error: UnicodetoUTF8 failed");
3641 NULLFREE(tmpbuf);
3642 return 0;
3643 }
3644 }
3645
3646 else if(iso_mode == -3)
3647 {
3648 memcpy(buf, source+offset, sourcelen-offset);
3649 buf[sourcelen-offset] = '\0';
3650
3651 cs_log_dbg(D_DVBAPI, "sdt-info dbg: iso_mode: -3 offset: %u", offset);
3652 }
3653
3654 cs_log_dump_dbg(D_DVBAPI, (uint8_t*)buf, strlen(buf), "sdt-info dbg: encoded string: ");
3655
3656 NULLFREE(tmpbuf);
3657 return 1;
3658}
3659
3660static void dvbapi_create_srvid_line(int32_t demux_id, char *buffer, uint32_t buflen)
3661{
3662 int32_t i, j;
3663 uint16_t caid_done[32], cur_caid;
3664 uint8_t caid_done_count = 0, skip_caid;
3665 int32_t pos = 0;
3666
3667 if(demux[demux_id].ECMpidcount == 0)
3668 {
3669 snprintf(buffer, buflen, "%04X@%06X", NO_CAID_VALUE, NO_PROVID_VALUE);
3670 return;
3671 }
3672
3673 for(i=0; i < demux[demux_id].ECMpidcount && i < 32; i++)
3674 {
3675 skip_caid = 0;
3676
3677 for(j=0; j < caid_done_count; j++)
3678 {
3679 if(caid_done[j] == demux[demux_id].ECMpids[i].CAID)
3680 {
3681 skip_caid = 1;
3682 break;
3683 }
3684 }
3685
3686 if(skip_caid)
3687 {
3688 continue;
3689 }
3690
3691 cur_caid = demux[demux_id].ECMpids[i].CAID;
3692 pos += snprintf(buffer+pos, buflen-pos, "%s%04X", caid_done_count > 0 ? "," : "", cur_caid == 0 ? NO_CAID_VALUE : cur_caid);
3693
3694 for(j=i; j < demux[demux_id].ECMpidcount; j++)
3695 {
3696 if(demux[demux_id].ECMpids[j].PROVID == 0)
3697 {
3698 continue;
3699 }
3700
3701 if(cur_caid == demux[demux_id].ECMpids[j].CAID)
3702 {
3703 pos += snprintf(buffer+pos, buflen-pos, "@%06X", demux[demux_id].ECMpids[j].PROVID);
3704 }
3705 }
3706
3707 caid_done[caid_done_count] = demux[demux_id].ECMpids[i].CAID;
3708 caid_done_count++;
3709 }
3710}
3711
3712static const char *dvbapi_get_service_type(uint8_t service_type_id)
3713{
3714 switch(service_type_id)
3715 {
3716 case 0x01:
3717 case 0x11:
3718 default:
3719 return "TV";
3720
3721 case 0x02:
3722 case 0x07:
3723 case 0x0A:
3724 return "Radio";
3725
3726 case 0x03:
3727 return "Teletext";
3728
3729 case 0x0C:
3730 return "Data";
3731 }
3732}
3733
3734static void dvbapi_parse_sdt(int32_t demux_id, unsigned char *buffer, uint32_t length)
3735{
3736 uint8_t tag, data_length = 0, provider_name_length, service_name_length, service_type;
3737 uint16_t service_id, descriptor_length, dpos;
3738 int32_t provid, caid;
3739 uint32_t section_length, pos;
3740 int32_t pidindex;
3741 char provider_name[64], service_name[64], tmp[256], srvid_line[1024];
3742 const char *type;
3743 FILE *fpsave = NULL;
3744 int8_t did_save_srvid = 0;
3745
3746 cs_log_dump_dbg(D_DVBAPI, buffer, length, "sdt-info dbg: sdt data: ");
3747
3748 if(length < 3)
3749 { return; }
3750
3751 if(buffer[0] != 0x42)
3752 { return; }
3753
3754 section_length = b2i(2, buffer + 1) &0xFFF;
3755
3756 if(section_length+3 != length)
3757 { return; }
3758
3759 for(pos = 11; pos+5 < length; pos += descriptor_length)
3760 {
3761 service_id = b2i(2, buffer + pos);
3762 descriptor_length = b2i(2, buffer + pos + 3) &0xFFF;
3763
3764 if((pos+5+descriptor_length) >= length)
3765 { return; }
3766
3767 pos += 5;
3768
3769 if(service_id != demux[demux_id].program_number)
3770 { continue; }
3771
3772 for(dpos = 0; dpos+1 < descriptor_length; dpos += (2 + data_length))
3773 {
3774 tag = buffer[pos+dpos];
3775 data_length = buffer[pos+dpos+1];
3776
3777 if(dpos+1+data_length >= descriptor_length)
3778 { break; }
3779
3780 if(tag != 0x48)
3781 { continue; }
3782
3783 if(dpos+3 >= descriptor_length)
3784 { break; }
3785
3786 service_type = buffer[pos+dpos+2];
3787
3788 provider_name_length = buffer[pos+dpos+3];
3789 if((dpos+4+provider_name_length+1) > descriptor_length)
3790 { break; }
3791
3792 service_name_length = buffer[pos+dpos+4+provider_name_length];
3793 if((dpos+4+provider_name_length+1+service_name_length) > descriptor_length)
3794 { break; }
3795
3796 pidindex = demux[demux_id].pidindex;
3797
3798 if (pidindex !=-1)
3799 {
3800 provid = demux[demux_id].ECMpids[pidindex].PROVID;
3801 caid = demux[demux_id].ECMpids[pidindex].CAID;
3802 }
3803 else
3804 {
3805 if(demux[demux_id].ECMpidcount == 0 || demux[demux_id].ECMpids[0].CAID == 0)
3806 {
3807 caid = NO_CAID_VALUE;
3808 provid = NO_PROVID_VALUE;
3809 }
3810 else
3811 {
3812 caid = demux[demux_id].ECMpids[0].CAID;
3813 provid = demux[demux_id].ECMpids[0].PROVID;
3814 }
3815 }
3816
3817 if(!dvbapi_extract_sdt_string(provider_name, sizeof(provider_name), buffer+pos+dpos+4, provider_name_length))
3818 { break; }
3819
3820 if(!dvbapi_extract_sdt_string(service_name, sizeof(service_name), buffer+pos+dpos+4+provider_name_length+1, service_name_length))
3821 { break; }
3822
3823 cs_log("sdt-info (provider: %s - channel: %s)", provider_name, service_name);
3824
3825 dvbapi_stop_filter(demux_id, TYPE_SDT);
3826
3827 if(strlen(provider_name) && caid != NO_CAID_VALUE)
3828 {
3829 get_providername_or_null(provid, caid, tmp, sizeof(tmp));
3830
3831 if(tmp[0] == '\0')
3832 {
3833 get_config_filename(tmp, sizeof(tmp), "oscam.provid");
3834
3835 if((fpsave = fopen(tmp, "a")))
3836 {
3837 fprintf(fpsave, "\n%04X@%06X|%s|", caid, provid, provider_name);
3838 fclose(fpsave);
3839
3840 init_provid();
3841 }
3842 }
3843 }
3844
3845 if(strlen(service_name))
3846 {
3847 get_servicename_or_null(cur_client(), service_id, provid, caid, tmp, sizeof(tmp));
3848
3849 if(tmp[0] == '\0')
3850 {
3851 type = dvbapi_get_service_type(service_type);
3852
3853 get_config_filename(tmp, sizeof(tmp), "oscam.srvid2");
3854
3855 if(!access(tmp, F_OK) && (fpsave = fopen(tmp, "a")))
3856 {
3857 if((caid != NO_CAID_VALUE) || (cfg.dvbapi_read_sdt > 1))
3858 {
3859 dvbapi_create_srvid_line(demux_id, srvid_line, sizeof(srvid_line));
3860
3861 if(cfg.dvbapi_write_sdt_prov)
3862 { fprintf(fpsave, "\n%04X:%s|%s|%s||%s", service_id, srvid_line, service_name, type, provider_name); }
3863 else
3864 { fprintf(fpsave, "\n%04X:%s|%s|%s", service_id, srvid_line, service_name, type); }
3865
3866 did_save_srvid = 1;
3867 }
3868 }
3869 else
3870 {
3871 get_config_filename(tmp, sizeof(tmp), "oscam.srvid");
3872
3873 if((fpsave = fopen(tmp, "a")))
3874 {
3875 if((caid != NO_CAID_VALUE) || (cfg.dvbapi_read_sdt > 1))
3876 {
3877 dvbapi_create_srvid_line(demux_id, srvid_line, sizeof(srvid_line));
3878
3879 if(cfg.dvbapi_write_sdt_prov)
3880 { fprintf(fpsave, "\n%s:%04X|%s|%s|%s", srvid_line, service_id, provider_name, service_name, type); }
3881
3882 else
3883 { fprintf(fpsave, "\n%s:%04X||%s|%s", srvid_line, service_id, service_name, type); }
3884
3885 did_save_srvid = 1;
3886 }
3887 }
3888 }
3889
3890 if(fpsave)
3891 { fclose(fpsave); }
3892
3893 if(did_save_srvid)
3894 { init_srvid(); }
3895 }
3896 }
3897
3898 return;
3899 }
3900 }
3901}
3902
3903static void dvbapi_parse_pat(int32_t demux_id, unsigned char *buffer, uint32_t length)
3904{
3905 uint16_t srvid;
3906 uint32_t i;
3907
3908 dvbapi_stop_filter(demux_id, TYPE_PAT);
3909
3910 for(i=8; i+7<length; i+=4)
3911 {
3912 srvid = b2i(2, buffer+i);
3913
3914 if(srvid == 0)
3915 { continue; }
3916
3917 if(demux[demux_id].program_number == srvid)
3918 {
3919 dvbapi_start_pmt_filter(demux_id, b2i(2, buffer+i+2) & 0x1FFF);
3920 break;
3921 }
3922 }
3923}
3924
3925int32_t dvbapi_init_listenfd(void)
3926{
3927 int32_t clilen, listenfd;
3928 struct sockaddr_un servaddr;
3929
3930 memset(&servaddr, 0, sizeof(struct sockaddr_un));
3931 servaddr.sun_family = AF_UNIX;
3932 cs_strncpy(servaddr.sun_path, devices[selected_box].cam_socket_path, sizeof(servaddr.sun_path));
3933 clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
3934
3935 if((unlink(devices[selected_box].cam_socket_path) < 0) && (errno != ENOENT))
3936 { return 0; }
3937 if((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
3938 { return 0; }
3939 if(bind(listenfd, (struct sockaddr *)&servaddr, clilen) < 0)
3940 { return 0; }
3941 if(listen(listenfd, 5) < 0)
3942 { return 0; }
3943
3944 // change the access right on the camd.socket
3945 // this will allow oscam to run as root if needed
3946 // and still allow non root client to connect to the socket
3947 chmod(devices[selected_box].cam_socket_path, S_IRWXU | S_IRWXG | S_IRWXO);
3948
3949 return listenfd;
3950}
3951
3952int32_t dvbapi_net_init_listenfd(void)
3953{
3954 int32_t listenfd;
3955 struct SOCKADDR servaddr;
3956
3957 memset(&servaddr, 0, sizeof(servaddr));
3958 SIN_GET_FAMILY(servaddr) = DEFAULT_AF;
3959 SIN_GET_ADDR(servaddr) = ADDR_ANY;
3960 SIN_GET_PORT(servaddr) = htons((uint16_t)cfg.dvbapi_listenport);
3961
3962 if((listenfd = socket(DEFAULT_AF, SOCK_STREAM, 0)) < 0)
3963 { return 0; }
3964
3965 int32_t opt = 0;
3966#ifdef IPV6SUPPORT
3967
3968 // azbox toolchain do not have this define
3969#ifndef IPV6_V6ONLY
3970#define IPV6_V6ONLY 26
3971#endif
3972
3973 // set the server socket option to listen on IPv4 and IPv6 simultaneously
3974 setsockopt(listenfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&opt, sizeof(opt));
3975#endif
3976
3977 opt = 1;
3978 setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt));
3979 set_so_reuseport(listenfd);
3980
3981 if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
3982 { return 0; }
3983 if(listen(listenfd, 5) < 0)
3984 { return 0; }
3985
3986 return listenfd;
3987}
3988
3989static pthread_mutex_t event_handler_lock;
3990
3991void event_handler(int32_t UNUSED(signal))
3992{
3993 struct stat pmt_info;
3994 char dest[1024];
3995 DIR *dirp;
3996 struct dirent entry, *dp = NULL;
3997 int32_t i, pmt_fd;
3998 uchar mbuf[2048]; // dirty fix: larger buffer needed for CA PMT mode 6 with many parallel channels to decode
3999 if(dvbapi_client != cur_client()) { return; }
4000
4001 SAFE_MUTEX_LOCK(&event_handler_lock);
4002
4003 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX || cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
4004 { pausecam = 0; }
4005 else
4006 {
4007 int32_t standby_fd = open(STANDBY_FILE, O_RDONLY);
4008 pausecam = (standby_fd > 0) ? 1 : 0;
4009 if(standby_fd > 0)
4010 {
4011 int32_t ret = close(standby_fd);
4012 if(ret < 0) { cs_log("ERROR: Could not close standby fd (errno=%d %s)", errno, strerror(errno)); }
4013 }
4014 }
4015
4016 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX || cfg.dvbapi_pmtmode == 1)
4017 {
4018 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4019 return;
4020 }
4021
4022 for(i = 0; i < MAX_DEMUX; i++)
4023 {
4024 if(demux[i].pmt_file[0] != 0)
4025 {
4026 snprintf(dest, sizeof(dest), "%s%s", TMPDIR, demux[i].pmt_file);
4027 pmt_fd = open(dest, O_RDONLY);
4028 if(pmt_fd > 0)
4029 {
4030 if(fstat(pmt_fd, &pmt_info) != 0)
4031 {
4032 int32_t ret = close(pmt_fd);
4033 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4034 continue;
4035 }
4036
4037 if((time_t)pmt_info.st_mtime != demux[i].pmt_time)
4038 {
4039 dvbapi_stop_descrambling(i);
4040 }
4041
4042 int32_t ret = close(pmt_fd);
4043 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4044 continue;
4045 }
4046 else
4047 {
4048 cs_log("Demuxer %d Unable to open PMT file %s -> stop descrambling!", i, dest);
4049 dvbapi_stop_descrambling(i);
4050 }
4051 }
4052 }
4053
4054 if(disable_pmt_files)
4055 {
4056 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4057 return;
4058 }
4059
4060 dirp = opendir(TMPDIR);
4061 if(!dirp)
4062 {
4063 cs_log_dbg(D_DVBAPI, "opendir failed (errno=%d %s)", errno, strerror(errno));
4064 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4065 return;
4066 }
4067
4068 while(!cs_readdir_r(dirp, &entry, &dp))
4069 {
4070 if(!dp) { break; }
4071
4072 if(strlen(dp->d_name) < 7)
4073 { continue; }
4074 if(strncmp(dp->d_name, "pmt", 3) != 0 || strncmp(dp->d_name + strlen(dp->d_name) - 4, ".tmp", 4) != 0)
4075 { continue; }
4076#if defined(WITH_STAPI) || defined(WITH_STAPI5)
4077 struct s_dvbapi_priority *p;
4078 for(p = dvbapi_priority; p != NULL; p = p->next) // stapi: check if there is a device connected to this pmt file!
4079 {
4080 if(p->type != 's') { continue; } // stapi rule?
4081 if(strcmp(dp->d_name, p->pmtfile) != 0) { continue; } // same file?
4082 break; // found match!
4083 }
4084 if(p == NULL)
4085 {
4086 cs_log_dbg(D_DVBAPI, "No matching S: line in oscam.dvbapi for pmtfile %s -> skip!", dp->d_name);
4087 continue;
4088 }
4089#endif
4090 snprintf(dest, sizeof(dest), "%s%s", TMPDIR, dp->d_name);
4091 pmt_fd = open(dest, O_RDONLY);
4092 if(pmt_fd < 0)
4093 { continue; }
4094
4095 if(fstat(pmt_fd, &pmt_info) != 0)
4096 {
4097 int32_t ret = close(pmt_fd);
4098 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4099 continue;
4100 }
4101
4102 int32_t found = 0;
4103 for(i = 0; i < MAX_DEMUX; i++)
4104 {
4105 if(strcmp(demux[i].pmt_file, dp->d_name) == 0)
4106 {
4107 if((time_t)pmt_info.st_mtime == demux[i].pmt_time)
4108 {
4109 found = 1;
4110 break;
4111 }
4112 }
4113 }
4114 if(found)
4115 {
4116 int32_t ret = close(pmt_fd);
4117 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4118 continue;
4119 }
4120
4121 cs_log_dbg(D_DVBAPI, "found pmt file %s", dest);
4122 cs_sleepms(100);
4123
4124 uint32_t len = read(pmt_fd, mbuf, sizeof(mbuf));
4125 int32_t ret = close(pmt_fd);
4126 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4127
4128 if(len < 1)
4129 {
4130 cs_log_dbg(D_DVBAPI, "pmt file %s have invalid len!", dest);
4131 continue;
4132 }
4133
4134 int32_t pmt_id;
4135
4136#ifdef QBOXHD
4137 uint32_t j1, j2;
4138 // QboxHD pmt.tmp is the full capmt written as a string of hex values
4139 // pmt.tmp must be longer than 3 bytes (6 hex chars) and even length
4140 if((len < 6) || ((len % 2) != 0) || ((len / 2) > sizeof(dest)))
4141 {
4142 cs_log_dbg(D_DVBAPI, "error parsing QboxHD pmt.tmp, incorrect length");
4143 continue;
4144 }
4145
4146 for(j2 = 0, j1 = 0; j2 < len; j2 += 2, j1++)
4147 {
4148 unsigned int tmp;
4149 if(sscanf((char *)mbuf + j2, "%02X", &tmp) != 1)
4150 {
4151 cs_log_dbg(D_DVBAPI, "error parsing QboxHD pmt.tmp, data not valid in position %d", j2);
4152 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4153 return;
4154 }
4155 else
4156 {
4157 memcpy(dest + j1, &tmp, 4);
4158 }
4159 }
4160
4161 cs_log_dump_dbg(D_DVBAPI, (unsigned char *)dest, len / 2, "QboxHD pmt.tmp:");
4162 pmt_id = dvbapi_parse_capmt((unsigned char *)dest + 4, (len / 2) - 4, -1, dp->d_name, 0, 0, 0);
4163#else
4164 if(len > sizeof(dest))
4165 {
4166 cs_log_dbg(D_DVBAPI, "event_handler() dest buffer is to small for pmt data!");
4167 continue;
4168 }
4169 if(len < 16)
4170 {
4171 cs_log_dbg(D_DVBAPI, "event_handler() received pmt is too small! (%d < 16 bytes!)", len);
4172 continue;
4173 }
4174 cs_log_dump_dbg(D_DVBAPI, mbuf, len, "pmt:");
4175
4176 dest[0] = 0x03;
4177 dest[1] = mbuf[3];
4178 dest[2] = mbuf[4];
4179 uint32_t pmt_program_length = b2i(2, mbuf + 10)&0xFFF;
4180 i2b_buf(2, pmt_program_length + 1, (uchar *) dest + 4);
4181 dest[6] = 0;
4182
4183 memcpy(dest + 7, mbuf + 12, len - 12 - 4);
4184
4185 pmt_id = dvbapi_parse_capmt((uchar *)dest, 7 + len - 12 - 4, -1, dp->d_name, 0, 0, 0);
4186#endif
4187
4188 if(pmt_id >= 0)
4189 {
4190 cs_strncpy(demux[pmt_id].pmt_file, dp->d_name, sizeof(demux[pmt_id].pmt_file));
4191 demux[pmt_id].pmt_time = (time_t)pmt_info.st_mtime;
4192 }
4193
4194 if(cfg.dvbapi_pmtmode == 3)
4195 {
4196 disable_pmt_files = 1;
4197 break;
4198 }
4199 }
4200 closedir(dirp);
4201 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4202}
4203
4204void *dvbapi_event_thread(void *cli)
4205{
4206 struct s_client *client = (struct s_client *) cli;
4207 SAFE_SETSPECIFIC(getclient, client);
4208 set_thread_name(__func__);
4209 while(!exit_oscam)
4210 {
4211 cs_sleepms(750);
4212 event_handler(0);
4213 }
4214
4215 return NULL;
4216}
4217
4218void dvbapi_process_input(int32_t demux_id, int32_t filter_num, uchar *buffer, int32_t len)
4219{
4220 struct s_ecmpids *curpid = NULL;
4221 int32_t pid = demux[demux_id].demux_fd[filter_num].pidindex;
4222 uint16_t filtertype = demux[demux_id].demux_fd[filter_num].type;
4223 uint32_t sctlen = SCT_LEN(buffer);
4224
4225 if((uint) len < sctlen) // invalid CAT length
4226 {
4227 cs_log_dbg(D_DVBAPI, "Received filterdata with total length 0x%03X but section length is 0x%03X -> invalid length!", len, sctlen);
4228 return;
4229 }
4230
4231 if(demux_id < 0 || demux_id >= MAX_DEMUX)
4232 {
4233 cs_log("dvbapi_process_input(): error - received invalid demux_id (%d)", demux_id);
4234 return;
4235 }
4236
4237 if(filter_num < 0 || filter_num >= MAX_FILTER)
4238 {
4239 cs_log("dvbapi_process_input(): error - received invalid filter_num (%d)", filter_num);
4240 return;
4241 }
4242
4243 if(pid != -1 && filtertype == TYPE_ECM)
4244 {
4245 curpid = &demux[demux_id].ECMpids[pid];
4246 }
4247
4248 int32_t filt_match = filtermatch(buffer, filter_num, demux_id, sctlen); // acts on all filters (sdt/emm/ecm)
4249 if(!filt_match)
4250 {
4251 cs_log_dbg(D_DVBAPI,"Demuxer %d receiver returned data that was not matching to the filter -> delivered filter data discarded!", demux_id);
4252 return;
4253 }
4254
4255 if(curpid && curpid->tries <= 0xF0 && filtertype == TYPE_ECM)
4256 {
4257 curpid->irdeto_maxindex = 0;
4258 curpid->irdeto_curindex = 0xFE;
4259 curpid->tries = 0xFE; // reset timeout retry flag
4260 curpid->irdeto_cycle = 0xFE; // reset irdetocycle
4261 curpid->table = 0;
4262 curpid->checked = 4; // flag ecmpid as checked
4263 curpid->status = -1; // flag ecmpid as unusable
4264 if(pid == demux[demux_id].pidindex)
4265 {
4266 demux[demux_id].pidindex = -1; // current pid delivered problems so this pid isnt being used to descramble any longer-> clear pidindex
4267 dvbapi_edit_channel_cache(demux_id, pid, 0); // remove this pid from channelcache since we had no founds on any ecmpid!
4268 }
4269 dvbapi_stop_filternum(demux_id, filter_num); // stop this ecm filter!
4270 return;
4271 }
4272
4273 if(filtertype == TYPE_ECM)
4274 {
4275 uint32_t chid = 0x10000;
4276 ECM_REQUEST *er;
4277
4278 if(len != 0) // len = 0 receiver encountered an internal bufferoverflow!
4279 {
4280 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched ECM data (ecmlength = 0x%03X):", demux_id, filter_num + 1, sctlen);
4281
4282 if(sctlen > MAX_ECM_SIZE) // ecm too long to handle!
4283 {
4284 cs_log_dbg(D_DVBAPI, "Received data with total length 0x%03X but maximum ECM length oscam can handle is 0x%03X -> Please report!", sctlen, MAX_ECM_SIZE);
4285 if(curpid)
4286 {
4287 curpid->tries-=0x0E;
4288 }
4289 return;
4290 }
4291
4292 if(!(buffer[0] == 0x80 || buffer[0] == 0x81))
4293 {
4294 cs_log_dbg(D_DVBAPI, "Received an ECM with invalid ecmtable ID %02X -> ignoring!", buffer[0]);
4295 if(curpid)
4296 {
4297 curpid->tries--;
4298 }
4299 return;
4300 }
4301
4302 if(curpid->table == buffer[0] && !caid_is_irdeto(curpid->CAID)) // wait for odd / even ecm change (only not for irdeto!)
4303 {
4304
4305 if(!(er = get_ecmtask()))
4306 {
4307 return;
4308 }
4309
4310 er->srvid = demux[demux_id].program_number;
4311
4312#ifdef WITH_STAPI5
4313 cs_strncpy(er->dev_name, dev_list[demux[demux_id].dev_index].name, sizeof(dev_list[demux[demux_id].dev_index].name));
4314#endif
4315
4316 er->tsid = demux[demux_id].tsid;
4317 er->onid = demux[demux_id].onid;
4318 er->pmtpid = demux[demux_id].pmtpid;
4319 er->ens = demux[demux_id].enigma_namespace;
4320
4321 er->caid = curpid->CAID;
4322 er->pid = curpid->ECM_PID;
4323 er->prid = curpid->PROVID;
4324 er->vpid = curpid->VPID;
4325 er->ecmlen = sctlen;
4326 memcpy(er->ecm, buffer, er->ecmlen);
4327 chid = get_subid(er); // fetch chid or fake chid
4328 er->chid = chid;
4329 dvbapi_set_section_filter(demux_id, er, filter_num);
4330 NULLFREE(er);
4331 return;
4332 }
4333
4334 if(caid_is_irdeto(curpid->CAID))
4335 {
4336 // 80 70 39 53 04 05 00 88
4337 // 81 70 41 41 01 06 00 13 00 06 80 38 1F 52 93 D2
4338 //if (buffer[5]>20) return;
4339 if(curpid->irdeto_maxindex != buffer[5]) //6, register max irdeto index
4340 {
4341 cs_log_dbg(D_DVBAPI, "Found %d IRDETO ECM CHIDs", buffer[5] + 1);
4342 curpid->irdeto_maxindex = buffer[5]; // numchids = 7 (0..6)
4343 }
4344 }
4345 }
4346
4347 if(!(er = get_ecmtask()))
4348 {
4349 return;
4350 }
4351
4352 er->srvid = demux[demux_id].program_number;
4353
4354#ifdef WITH_STAPI5
4355 cs_strncpy(er->dev_name, dev_list[demux[demux_id].dev_index].name, sizeof(dev_list[demux[demux_id].dev_index].name));
4356#endif
4357
4358 er->tsid = demux[demux_id].tsid;
4359 er->onid = demux[demux_id].onid;
4360 er->pmtpid = demux[demux_id].pmtpid;
4361 er->ens = demux[demux_id].enigma_namespace;
4362
4363 er->caid = curpid->CAID;
4364 er->pid = curpid->ECM_PID;
4365 er->prid = curpid->PROVID;
4366 er->vpid = curpid->VPID;
4367 er->ecmlen = sctlen;
4368 memcpy(er->ecm, buffer, er->ecmlen);
4369
4370 chid = get_subid(er); // fetch chid or fake chid
4371 uint32_t fixedprovid = chk_provid(er->ecm, er->caid);
4372 if(fixedprovid && fixedprovid != er->prid)
4373 {
4374 cs_log_dbg(D_DVBAPI, "Fixing provid ecmpid %d from %06X -> %06X", pid, curpid->PROVID, fixedprovid);
4375 curpid->PROVID = fixedprovid;
4376 if(!USE_OPENXCAS)
4377 {
4378 cs_log_dbg(D_DVBAPI, "Fixing provid filter %d from %06X -> %06X", filter_num+1, demux[demux_id].demux_fd[filter_num].provid, fixedprovid);
4379 demux[demux_id].demux_fd[filter_num].provid = fixedprovid;
4380 }
4381 cs_log_dbg(D_DVBAPI, "Fixing provid ecmrequest from %06X -> %06X", er->prid, fixedprovid);
4382 er->prid = fixedprovid;
4383 }
4384 er->chid = chid;
4385
4386 if(len == 0) // only used on receiver internal bufferoverflow to get quickly fresh ecm filterdata otherwise freezing!
4387 {
4388 curpid->table = 0;
4389 dvbapi_set_section_filter(demux_id, er, filter_num);
4390 NULLFREE(er);
4391 return;
4392 }
4393
4394 if(caid_is_irdeto(curpid->CAID))
4395 {
4396
4397 if(curpid->irdeto_curindex != buffer[4]) // old style wrong irdeto index
4398 {
4399 if(curpid->irdeto_curindex == 0xFE) // check if this ecmfilter just started up
4400 {
4401 curpid->irdeto_curindex = buffer[4]; // on startup set the current index to the irdeto index of the ecm
4402 }
4403 else // we are already running and not interested in this ecm
4404 {
4405 if(curpid->table != buffer[0]) curpid->table = 0; // fix for receivers not supporting section filtering
4406 dvbapi_set_section_filter(demux_id, er, filter_num); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4407 NULLFREE(er);
4408 return;
4409 }
4410 }
4411 else //fix for receivers not supporting section filtering
4412 {
4413 if(curpid->table == buffer[0]){
4414 NULLFREE(er);
4415 return;
4416 }
4417 }
4418 cs_log_dbg(D_DVBAPI, "Demuxer %d ECMTYPE %02X CAID %04X PROVID %06X ECMPID %04X IRDETO INDEX %02X MAX INDEX %02X CHID %04X CYCLE %02X VPID %04X", demux_id, er->ecm[0], er->caid, er->prid, er->pid, er->ecm[4], er->ecm[5], er->chid, curpid->irdeto_cycle, er->vpid);
4419 }
4420 else
4421 {
4422 cs_log_dbg(D_DVBAPI, "Demuxer %d ECMTYPE %02X CAID %04X PROVID %06X ECMPID %04X FAKECHID %04X (unique part in ecm)",
4423 demux_id, er->ecm[0], er->caid, er->prid, er->pid, er->chid);
4424 }
4425
4426 // check for matching chid (unique ecm part in case of non-irdeto cas) + added fix for seca2 monthly changing fakechid
4427 if((curpid->CHID < 0x10000) && !((chid == curpid->CHID) || ((curpid->CAID >> 8 == 0x01) && (chid&0xF0FF) == (curpid->CHID&0xF0FF)) ) )
4428 {
4429 if(caid_is_irdeto(curpid->CAID))
4430 {
4431
4432 if((curpid->irdeto_cycle < 0xFE) && (curpid->irdeto_cycle == curpid->irdeto_curindex)) // if same: we cycled all indexes but no luck!
4433 {
4434 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match(demux_id, pid, 'p');
4435 if(!forceentry || !forceentry->force) // forced pid? keep trying the forced ecmpid, no force kill ecm filter
4436 {
4437 if(curpid->checked == 2) { curpid->checked = 4; }
4438 if(curpid->checked == 1)
4439 {
4440 curpid->checked = 2;
4441 curpid->CHID = 0x10000;
4442 }
4443 dvbapi_stop_filternum(demux_id, filter_num); // stop this ecm filter!
4444 NULLFREE(er);
4445 return;
4446 }
4447 }
4448
4449 curpid->irdeto_curindex++; // set check on next index
4450 if(curpid->irdeto_cycle == 0xFE) curpid->irdeto_cycle = buffer[4]; // on startup set to current irdeto index
4451 if(curpid->irdeto_curindex > curpid->irdeto_maxindex) { curpid->irdeto_curindex = 0; } // check if we reached max irdeto index, if so reset to 0
4452
4453 curpid->table = 0;
4454 dvbapi_set_section_filter(demux_id, er, filter_num); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4455 NULLFREE(er);
4456 return;
4457 }
4458 else // all nonirdeto cas systems
4459 {
4460 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match(demux_id, pid, 'p');
4461 curpid->table = 0;
4462 dvbapi_set_section_filter(demux_id, er, filter_num); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4463 if(forceentry && forceentry->force)
4464 {
4465 NULLFREE(er);
4466 return; // forced pid? keep trying the forced ecmpid!
4467 }
4468 if(curpid->checked == 2) { curpid->checked = 4; }
4469 if(curpid->checked == 1)
4470 {
4471 curpid->checked = 2;
4472 curpid->CHID = 0x10000;
4473 }
4474 dvbapi_stop_filternum(demux_id, filter_num); // stop this ecm filter!
4475 NULLFREE(er);
4476 return;
4477 }
4478 }
4479
4480 struct s_dvbapi_priority *p;
4481
4482 for(p = dvbapi_priority; p != NULL; p = p->next)
4483 {
4484 if(p->type != 'l'
4485 || (p->caid && p->caid != curpid->CAID)
4486 || (p->provid && p->provid != curpid->PROVID)
4487 || (p->ecmpid && p->ecmpid != curpid->ECM_PID)
4488 || (p->srvid && p->srvid != demux[demux_id].program_number))
4489 { continue; }
4490
4491 if((uint)p->delay == sctlen && p->force < 6)
4492 {
4493 p->force++;
4494 NULLFREE(er);
4495 return;
4496 }
4497 if(p->force >= 6)
4498 { p->force = 0; }
4499 }
4500
4501 if(!curpid->PROVID)
4502 { curpid->PROVID = chk_provid(buffer, curpid->CAID); }
4503
4504 if(caid_is_irdeto(curpid->CAID)) // irdeto: wait for the correct index
4505 {
4506 if(buffer[4] != curpid->irdeto_curindex)
4507 {
4508 curpid->table = 0;
4509 dvbapi_set_section_filter(demux_id, er, filter_num); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4510 NULLFREE(er);
4511 return;
4512 }
4513 }
4514 // we have an ecm with the correct irdeto index (or fakechid)
4515 for(p = dvbapi_priority; p != NULL ; p = p->next) // check for ignore!
4516 {
4517 if((p->type != 'i')
4518 || (p->caid && p->caid != curpid->CAID)
4519 || (p->provid && p->provid != curpid->PROVID)
4520 || (p->ecmpid && p->ecmpid != curpid->ECM_PID)
4521 || (p->pidx && p->pidx-1 != pid)
4522 || (p->srvid && p->srvid != demux[demux_id].program_number))
4523 { continue; }
4524
4525 if(p->type == 'i' && (p->chid < 0x10000 && p->chid == chid)) // found a ignore chid match with current ecm -> ignoring this irdeto index
4526 {
4527 curpid->irdeto_curindex++;
4528 if(curpid->irdeto_cycle == 0xFE) curpid->irdeto_cycle = buffer[4]; // on startup set to current irdeto index
4529 if(curpid->irdeto_curindex > curpid->irdeto_maxindex) // check if curindex is over the max
4530 {
4531 curpid->irdeto_curindex = 0;
4532 }
4533 curpid->table = 0;
4534 if(caid_is_irdeto(curpid->CAID) && (curpid->irdeto_cycle != curpid->irdeto_curindex)) // irdeto: wait for the correct index + check if we cycled all
4535 {
4536 dvbapi_set_section_filter(demux_id, er, filter_num); // set ecm filter to odd + even since this chid has to be ignored!
4537 }
4538 else // this fakechid has to be ignored, kill this filter!
4539 {
4540 if(curpid->checked == 2) { curpid->checked = 4; }
4541 if(curpid->checked == 1)
4542 {
4543 curpid->checked = 2;
4544 curpid->CHID = 0x10000;
4545 }
4546 dvbapi_stop_filternum(demux_id, filter_num); // stop this ecm filter!
4547 }
4548 NULLFREE(er);
4549 return;
4550 }
4551 }
4552
4553 if(er) curpid->table = er->ecm[0];
4554 request_cw(dvbapi_client, er, demux_id, 1); // register this ecm for delayed ecm response check
4555 return; // end of ecm filterhandling!
4556 }
4557
4558 if(filtertype == TYPE_EMM)
4559 {
4560 if(len != 0) // len = 0 receiver encountered an internal bufferoverflow!
4561 {
4562 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched EMM data (emmlength = 0x%03X):", demux_id, filter_num + 1, sctlen);
4563
4564 if(sctlen > MAX_EMM_SIZE) // emm too long to handle!
4565 {
4566 cs_log_dbg(D_DVBAPI, "Received data with total length 0x%03X but maximum EMM length oscam can handle is 0x%03X -> Please report!", sctlen, MAX_EMM_SIZE);
4567 return;
4568 }
4569 }
4570 else
4571 {
4572 return; // just skip on internal bufferoverflow
4573 }
4574
4575
4576 if(demux[demux_id].demux_fd[filter_num].pid == 0x01) // CAT
4577 {
4578 cs_log_dbg(D_DVBAPI, "receiving cat");
4579 dvbapi_parse_cat(demux_id, buffer, sctlen);
4580
4581 dvbapi_stop_filternum(demux_id, filter_num);
4582 return;
4583 }
4584 dvbapi_process_emm(demux_id, filter_num, buffer, sctlen);
4585 }
4586
4587 if(filtertype == TYPE_SDT)
4588 {
4589 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched SDT data (length = 0x%03X):", demux_id, filter_num + 1, sctlen);
4590 dvbapi_parse_sdt(demux_id, buffer, sctlen);
4591 }
4592
4593 if(filtertype == TYPE_PAT)
4594 {
4595 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched PAT data (length = 0x%03X):", demux_id, filter_num + 1, sctlen);
4596 dvbapi_parse_pat(demux_id, buffer, sctlen);
4597 }
4598
4599 if(filtertype == TYPE_PMT)
4600 {
4601 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched CAPMT data (length = 0x%03X):", demux_id, filter_num + 1, sctlen);
4602 dvbapi_parse_capmt(buffer, sctlen, demux[demux_id].socket_fd, demux[demux_id].pmt_file, 1, demux_id, demux[demux_id].client_proto_version);
4603 }
4604}
4605
4606static int32_t dvbapi_recv(int32_t connfd, uchar* mbuf, size_t rlen)
4607{
4608 ssize_t len = cs_recv(connfd, mbuf, rlen, MSG_DONTWAIT);
4609
4610 if((len == -1 && (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK)) || (len == 0))
4611 {
4612 return -1;
4613 }
4614
4615 if(len == -1)
4616 {
4617 return 0;
4618 }
4619
4620 return len;
4621}
4622
4623static uint16_t dvbapi_get_nbof_missing_header_bytes(uchar* mbuf, uint16_t mbuf_len)
4624{
4625 if(mbuf_len < 4)
4626 {
4627 return 4 - mbuf_len;
4628 }
4629
4630 uint32_t opcode = b2i(4, mbuf); //get the client opcode (4 bytes)
4631
4632 //detect the opcode, its size (chunksize) and its internal data size (data_len)
4633 if((opcode & 0xFFFFF000) == DVBAPI_AOT_CA) // min 4+size bytes
4634 {
4635 if(mbuf[3] & 0x80)
4636 {
4637 uint32_t size = mbuf[3] & 0x7F;
4638
4639 if(mbuf_len < (4+size))
4640 {
4641 return (4+size) - mbuf_len;
4642 }
4643 }
4644 return 0;
4645 }
4646 else switch (opcode)
4647 {
4648 case DVBAPI_FILTER_DATA: // min 9 bytes
4649 {
4650 if(mbuf_len < 9)
4651 {
4652 return 9 - mbuf_len;
4653 }
4654 return 0;
4655 }
4656 case DVBAPI_CLIENT_INFO: // min 7 bytes
4657 {
4658 if(mbuf_len < 7)
4659 {
4660 return 7 - mbuf_len;
4661 }
4662 return 0;
4663 }
4664 default:
4665 {
4666 return 0;
4667 }
4668 }
4669}
4670
4671static void dvbapi_get_packet_size(uchar* mbuf, uint16_t mbuf_len, uint16_t* chunksize, uint16_t *data_len)
4672{
4673 //chunksize: size of complete chunk in the buffer (an opcode with the data)
4674 //data_len: variable for internal data length (eg. for the filter data size, PMT len)
4675
4676 (*chunksize) = 0;
4677 (*data_len) = 0;
4678
4679 if(mbuf_len < 4)
4680 {
4681 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short", mbuf_len);
4682 (*chunksize) = 1;
4683 (*data_len) = 1;
4684 return;
4685 }
4686
4687 uint32_t opcode = b2i(4, mbuf); //get the client opcode (4 bytes)
4688
4689 //detect the opcode, its size (chunksize) and its internal data size (data_len)
4690 if((opcode & 0xFFFFF000) == DVBAPI_AOT_CA) // min 4+size bytes
4691 {
4692 // parse packet size (ASN.1)
4693 uint32_t size = 0;
4694
4695 if(mbuf[3] & 0x80)
4696 {
4697 uint32_t tmp_data_len = 0;
4698
4699 size = mbuf[3] & 0x7F;
4700
4701 if(3 + size < mbuf_len)
4702 {
4703 uint32_t k;
4704 for (k = 0; k < size; k++)
4705 {
4706 tmp_data_len = (tmp_data_len << 8) | mbuf[4 + k];
4707 }
4708 }
4709 else
4710 {
4711 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short for opcode %08X", mbuf_len, opcode);
4712 (*chunksize) = 1;
4713 (*data_len) = 1;
4714 return;
4715 }
4716
4717 if(tmp_data_len > 0xFFFF)
4718 {
4719 cs_log("Socket command too big: %d bytes", tmp_data_len);
4720 (*data_len) = 0xFFFF - 4 - size;
4721 }
4722 else
4723 {
4724 (*data_len) = tmp_data_len;
4725 }
4726 }
4727 else
4728 {
4729 (*data_len) = mbuf[3] & 0x7F;
4730 }
4731
4732 (*chunksize) = 4 + size + (*data_len);
4733
4734 cs_log_dbg(D_DVBAPI, "Got packet with opcode %08X and size %" PRIu16, opcode, (*chunksize));
4735 }
4736 else switch (opcode)
4737 {
4738 case DVBAPI_FILTER_DATA: // min 9 bytes
4739 {
4740 if(mbuf_len < 9)
4741 {
4742 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short for DVBAPI_FILTER_DATA", mbuf_len);
4743 (*chunksize) = 1;
4744 (*data_len) = 1;
4745 return;
4746 }
4747
4748 (*data_len) = b2i(2, mbuf + 7) & 0x0FFF;
4749 (*chunksize) = 6 + 3 + (*data_len);
4750
4751 cs_log_dbg(D_DVBAPI, "Got DVBAPI_FILTER_DATA packet with size %" PRIu16, (*chunksize));
4752 break;
4753 }
4754 case DVBAPI_CLIENT_INFO: // min 7 bytes
4755 {
4756 if(mbuf_len < 7)
4757 {
4758 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short for DVBAPI_CLIENT_INFO", mbuf_len);
4759 (*chunksize) = 1;
4760 (*data_len) = 1;
4761 return;
4762 }
4763
4764 (*data_len) = mbuf[6];
4765 (*chunksize) = 6 + 1 + (*data_len);
4766
4767 cs_log_dbg(D_DVBAPI, "Got DVBAPI_CLIENT_INFO packet with size %" PRIu16, (*chunksize));
4768 break;
4769 }
4770 default:
4771 {
4772 cs_log("Unknown socket command received: 0x%08X", opcode);
4773 (*chunksize) = 1;
4774 (*data_len) = 1;
4775 break;
4776 }
4777 }
4778
4779 if((*chunksize) < 1)
4780 {
4781 (*chunksize) = 1;
4782 (*data_len) = 1;
4783 }
4784}
4785
4786static void dvbapi_handlesockmsg(uchar* mbuf, uint16_t chunksize, uint16_t data_len, uint8_t* add_to_poll, int32_t connfd, uint16_t* client_proto_version)
4787{
4788 uint32_t opcode = b2i(4, mbuf); //get the client opcode (4 bytes)
4789
4790 if((opcode & 0xFFFFF000) == DVBAPI_AOT_CA)
4791 {
4792 switch(opcode & 0xFFFFFF00)
4793 {
4794 case DVBAPI_AOT_CA_PMT:
4795 {
4796 if(data_len < 5)
4797 {
4798 cs_log("Error: packet DVBAPI_AOT_CA_PMT is too short!");
4799 break;
4800 }
4801
4802 cs_log_dbg(D_DVBAPI, "PMT Update on socket %d.", connfd);
4803 cs_log_dump_dbg(D_DVBAPI, mbuf, chunksize, "Parsing PMT object:");
4804
4805 dvbapi_parse_capmt(mbuf + (chunksize - data_len), data_len, connfd, NULL, 0, 0, *client_proto_version);
4806 break;
4807 }
4808 case (DVBAPI_AOT_CA_STOP & 0xFFFFFF00):
4809 {
4810 // 9F 80 3f 04 83 02 00 <demux index>
4811 if(opcode != DVBAPI_AOT_CA_STOP)
4812 {
4813 cs_log_dbg(D_DVBAPI, "dvbapi_handlesockmsg(): DVBAPI_AOT_CA opcode unknown: %08X", opcode);
4814 break;
4815 }
4816 int32_t i;
4817
4818 if(data_len < 4)
4819 {
4820 cs_log("Error: packet DVBAPI_AOT_CA_STOP is too short!");
4821 break;
4822 }
4823
4824 // ipbox fix
4825 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX || cfg.dvbapi_listenport)
4826 {
4827 int32_t demux_index = mbuf[7];
4828 for(i = 0; i < MAX_DEMUX; i++)
4829 {
4830 // 0xff demux_index is a wildcard => close all related demuxers
4831 if(demux_index == 0xff)
4832 {
4833 if(demux[i].socket_fd == connfd)
4834 {
4835 dvbapi_stop_descrambling(i);
4836 }
4837 }
4838 else if (demux[i].demux_index == demux_index)
4839 {
4840 dvbapi_stop_descrambling(i);
4841 break;
4842 }
4843 }
4844 if (cfg.dvbapi_boxtype == BOXTYPE_IPBOX)
4845 {
4846 // check do we have any demux running on this fd
4847 int16_t execlose = 1;
4848 for(i = 0; i < MAX_DEMUX; i++)
4849 {
4850 if(demux[i].socket_fd == connfd)
4851 {
4852 execlose = 0;
4853 break;
4854 }
4855 }
4856 if(execlose)
4857 {
4858 int32_t ret = close(connfd);
4859 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4860 }
4861 }
4862 }
4863 else
4864 {
4865 if(cfg.dvbapi_pmtmode != 6)
4866 {
4867 int32_t ret = close(connfd);
4868 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4869 }
4870 }
4871 break;
4872 }
4873 default:
4874 {
4875 cs_log_dbg(D_DVBAPI, "dvbapi_handlesockmsg(): DVBAPI_AOT_CA opcode unknown: %08X", opcode);
4876 break;
4877 }
4878 }
4879
4880 if(cfg.dvbapi_listenport && opcode == DVBAPI_AOT_CA_STOP)
4881 {
4882 (*add_to_poll) = 1;
4883 }
4884 else
4885 {
4886 (*add_to_poll) = 0;
4887 }
4888 }
4889 else switch(opcode)
4890 {
4891 case DVBAPI_FILTER_DATA:
4892 {
4893 if(data_len < 1)
4894 {
4895 cs_log("Error: packet DVBAPI_FILTER_DATA is too short!");
4896 break;
4897 }
4898
4899 int32_t demux_id = mbuf[4];
4900 int32_t filter_num = mbuf[5];
4901
4902 if(demux_id < 0 || demux_id >= MAX_DEMUX)
4903 {
4904 cs_log("dvbapi_handlesockmsg(): error - received invalid demux_id (%d)", demux_id);
4905 break;
4906 }
4907
4908 if(filter_num < 0 || filter_num >= MAX_FILTER)
4909 {
4910 cs_log("dvbapi_handlesockmsg(): error - received invalid filter_num (%d)", filter_num);
4911 break;
4912 }
4913
4914 dvbapi_process_input(demux_id, filter_num, mbuf + 6, data_len + 3);
4915 break;
4916 }
4917 case DVBAPI_CLIENT_INFO:
4918 {
4919 uint16_t client_proto = b2i(2, mbuf + 4);
4920
4921 NULLFREE(last_client_name);
4922
4923 if(cs_malloc(&last_client_name, data_len + 1))
4924 {
4925 memcpy(last_client_name, &mbuf[7], data_len);
4926 last_client_name[data_len] = 0;
4927 cs_log("Client connected: '%s' (protocol version = %" PRIu16 ")", last_client_name, client_proto);
4928 }
4929
4930 (*client_proto_version) = client_proto; //setting the global var according to the client
4931 last_client_proto_version = client_proto;
4932
4933 // as a response we are sending our info to the client:
4934 dvbapi_net_send(DVBAPI_SERVER_INFO, connfd, -1, -1, NULL, NULL, NULL, client_proto);
4935 break;
4936 }
4937 default:
4938 {
4939 cs_log_dbg(D_DVBAPI, "dvbapi_handlesockmsg(): opcode unknown: %08X", opcode);
4940 cs_log_dump(mbuf, chunksize, "Unknown command:");
4941 break;
4942 }
4943 }
4944}
4945
4946static bool dvbapi_handlesockdata(int32_t connfd, uchar* mbuf, uint16_t mbuf_size, uint16_t unhandled_len,
4947 uint8_t* add_to_poll, uint16_t* new_unhandled_len, uint16_t* client_proto_version)
4948{
4949 int32_t recv_result;
4950 uint16_t chunksize = 1, data_len = 1;
4951 uint8_t packet_count = 0;
4952
4953 uint16_t missing_header_bytes = dvbapi_get_nbof_missing_header_bytes(mbuf, unhandled_len);
4954
4955 if(missing_header_bytes)
4956 {
4957 // read first few bytes so we know packet type and length
4958 cs_log_dbg(D_TRACE, "%s to read %" PRIu16 " bytes from connection fd %d", (unhandled_len == 0) ? "Trying":"Continue", missing_header_bytes, connfd);
4959
4960 recv_result = dvbapi_recv(connfd, mbuf + unhandled_len, mbuf_size - unhandled_len);
4961 if(recv_result < 1)
4962 {
4963 (*new_unhandled_len) = unhandled_len;
4964 return (recv_result != -1);
4965 }
4966 else
4967 {
4968 unhandled_len += recv_result;
4969
4970 if(unhandled_len < dvbapi_get_nbof_missing_header_bytes(mbuf, unhandled_len))
4971 {
4972 (*new_unhandled_len) = unhandled_len;
4973 return true;
4974 }
4975 }
4976 }
4977
4978 do
4979 {
4980 // we got at least the first few bytes, detect packet type and length, then read the missing bytes
4981 dvbapi_get_packet_size(mbuf, unhandled_len, &chunksize, &data_len);
4982
4983 if(chunksize > mbuf_size)
4984 {
4985 cs_log("***** WARNING: SOCKET DATA BUFFER OVERFLOW (%" PRIu16 " bytes), PLEASE REPORT! ****** ", chunksize);
4986 (*new_unhandled_len) = 0;
4987 return true;
4988 }
4989
4990 if(unhandled_len < chunksize) // we are missing some bytes, try to read them
4991 {
4992 cs_log_dbg(D_TRACE, "Continue to read %d bytes from connection fd %d", chunksize - unhandled_len, connfd);
4993
4994 recv_result = dvbapi_recv(connfd, mbuf + unhandled_len, mbuf_size - unhandled_len);
4995 if(recv_result < 1)
4996 {
4997 (*new_unhandled_len) = unhandled_len;
4998 return (recv_result != -1);
4999 }
5000 else
5001 {
5002 unhandled_len += recv_result;
5003
5004 if(unhandled_len < chunksize)
5005 {
5006 (*new_unhandled_len) = unhandled_len;
5007 return true;
5008 }
5009 }
5010 }
5011
5012 // we got at least one full packet, handle it, then return
5013 dvbapi_handlesockmsg(mbuf, chunksize, data_len, add_to_poll, connfd, client_proto_version);
5014
5015 unhandled_len -= chunksize;
5016
5017 if(unhandled_len > 0)
5018 {
5019 memmove(mbuf, mbuf + chunksize, unhandled_len);
5020 }
5021
5022 packet_count++;
5023
5024 } while(dvbapi_get_nbof_missing_header_bytes(mbuf, unhandled_len) == 0 && packet_count < 7);
5025
5026 (*new_unhandled_len) = unhandled_len;
5027 return true;
5028}
5029
5030static void *dvbapi_main_local(void *cli)
5031{
5032 int32_t i, j, l;
5033 struct s_client *client = (struct s_client *) cli;
5034 client->thread = pthread_self();
5035 SAFE_SETSPECIFIC(getclient, cli);
5036
5037 dvbapi_client = cli;
5038
5039 int32_t maxpfdsize = (MAX_DEMUX * maxfilter) + MAX_DEMUX + 2;
5040 struct pollfd pfd2[maxpfdsize];
5041 struct timeb start, end; // start time poll, end time poll
5042#define PMT_SERVER_SOCKET "/tmp/.listen.camd.socket"
5043 struct sockaddr_un saddr;
5044 saddr.sun_family = AF_UNIX;
5045 strncpy(saddr.sun_path, PMT_SERVER_SOCKET, 107);
5046 saddr.sun_path[107] = '\0';
5047
5048 int32_t rc, pfdcount, g, connfd, clilen;
5049 int32_t ids[maxpfdsize], fdn[maxpfdsize], type[maxpfdsize];
5050 struct SOCKADDR servaddr;
5051 ssize_t len = 0;
5052 static const uint16_t mbuf_size = 2048;
5053 uchar *mbuf;
5054 uint16_t unhandled_buf_len[maxpfdsize], unhandled_buf_used[maxpfdsize];
5055 uchar *unhandled_buf[maxpfdsize];
5056 struct s_auth *account;
5057 int32_t ok = 0;
5058 uint16_t client_proto_version[maxpfdsize];
5059
5060 if(!cs_malloc(&mbuf, sizeof(uchar)*mbuf_size))
5061 {
5062 return NULL;
5063 }
5064
5065 for(i = 0; i < maxpfdsize; i++)
5066 {
5067 unhandled_buf[i] = NULL;
5068 unhandled_buf_len[i] = 0;
5069 unhandled_buf_used[i] = 0;
5070
5071 client_proto_version[i] = 0;
5072 }
5073
5074 for(account = cfg.account; account != NULL; account = account->next)
5075 {
5076 if((ok = is_dvbapi_usr(account->usr)))
5077 { break; }
5078 }
5079 cs_auth_client(client, ok ? account : (struct s_auth *)(-1), "dvbapi");
5080
5081 memset(demux, 0, sizeof(struct demux_s) * MAX_DEMUX);
5082 for(i = 0; i < MAX_DEMUX; i++)
5083 {
5084 for(j = 0; j < ECM_PIDS; j++)
5085 {
5086 for(l = 0; l < MAX_STREAM_INDICES; l++)
5087 {
5088 demux[i].ECMpids[j].index[l] = INDEX_INVALID;
5089 }
5090 }
5091 }
5092
5093 memset(ca_fd, 0, sizeof(ca_fd));
5094 memset(unassoc_fd, 0, sizeof(unassoc_fd));
5095
5096 dvbapi_read_priority();
5097 dvbapi_load_channel_cache();
5098 dvbapi_detect_api();
5099
5100 if(selected_box == -1 || selected_api == -1)
5101 {
5102 cs_log("ERROR: Could not detect DVBAPI version.");
5103 free(mbuf);
5104 return NULL;
5105 }
5106
5107 if(cfg.dvbapi_pmtmode == 1)
5108 { disable_pmt_files = 1; }
5109
5110 int32_t listenfd = -1;
5111 if(cfg.dvbapi_boxtype != BOXTYPE_IPBOX_PMT && cfg.dvbapi_pmtmode != 2 && cfg.dvbapi_pmtmode != 5 && cfg.dvbapi_pmtmode != 6)
5112 {
5113 if (!cfg.dvbapi_listenport)
5114 listenfd = dvbapi_init_listenfd();
5115 else
5116 listenfd = dvbapi_net_init_listenfd();
5117 if(listenfd < 1)
5118 {
5119 cs_log("ERROR: Could not init socket: (errno=%d: %s)", errno, strerror(errno));
5120 free(mbuf);
5121 return NULL;
5122 }
5123 }
5124
5125 SAFE_MUTEX_INIT(&event_handler_lock, NULL);
5126
5127 for(i = 0; i < MAX_DEMUX; i++) // init all demuxers!
5128 {
5129 demux[i].pidindex = -1;
5130 demux[i].curindex = -1;
5131 }
5132
5133 if(cfg.dvbapi_pmtmode != 4 && cfg.dvbapi_pmtmode != 5 && cfg.dvbapi_pmtmode != 6)
5134 {
5135 struct sigaction signal_action;
5136 signal_action.sa_handler = event_handler;
5137 sigemptyset(&signal_action.sa_mask);
5138 signal_action.sa_flags = SA_RESTART;
5139 sigaction(SIGRTMIN + 1, &signal_action, NULL);
5140
5141 dir_fd = open(TMPDIR, O_RDONLY);
5142 if(dir_fd >= 0)
5143 {
5144 fcntl(dir_fd, F_SETSIG, SIGRTMIN + 1);
5145 fcntl(dir_fd, F_NOTIFY, DN_MODIFY | DN_CREATE | DN_DELETE | DN_MULTISHOT);
5146 event_handler(SIGRTMIN + 1);
5147 }
5148 }
5149 else
5150 {
5151 int32_t ret = start_thread("dvbapi event", dvbapi_event_thread, (void *) dvbapi_client, NULL, 1, 0);
5152 if(ret)
5153 {
5154 free(mbuf);
5155 return NULL;
5156 }
5157 }
5158
5159 if(listenfd != -1)
5160 {
5161 pfd2[0].fd = listenfd;
5162 pfd2[0].events = (POLLIN | POLLPRI);
5163 type[0] = 1;
5164 }
5165
5166#if defined WITH_COOLAPI || defined WITH_COOLAPI2
5167 system("pzapit -rz");
5168#endif
5169 cs_ftime(&start); // register start time
5170 while(!exit_oscam)
5171 {
5172 if(pausecam) // for dbox2, STAPI or PC in standby mode dont parse any ecm/emm or try to start next filter
5173 { continue; }
5174
5175 if(cfg.dvbapi_pmtmode == 6)
5176 {
5177 if(listenfd < 0)
5178 {
5179 cs_log("PMT6: Trying connect to enigma CA PMT listen socket...");
5180 /* socket init */
5181 if((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
5182 {
5183
5184 cs_log("socket error (errno=%d %s)", errno, strerror(errno));
5185 listenfd = -1;
5186 }
5187 else if(connect(listenfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
5188 {
5189 cs_log("socket connect error (errno=%d %s)", errno, strerror(errno));
5190 close(listenfd);
5191 listenfd = -1;
5192 }
5193 else
5194 {
5195 pfd2[0].fd = listenfd;
5196 pfd2[0].events = (POLLIN | POLLPRI);
5197 type[0] = 1;
5198 cs_log("PMT6 CA PMT Server connected on fd %d!", listenfd);
5199 }
5200 }
5201 if(listenfd == -1) // not connected!
5202 {
5203 cs_sleepms(1000);
5204 continue; // start fresh connect attempt!
5205 }
5206
5207 }
5208 pfdcount = (listenfd > -1) ? 1 : 0;
5209
5210 for(i = 0; i < MAX_DEMUX; i++)
5211 {
5212 // add client fd's which are not yet associated with the demux but needs to be polled for data
5213 if (unassoc_fd[i]) {
5214 pfd2[pfdcount].fd = unassoc_fd[i];
5215 pfd2[pfdcount].events = (POLLIN | POLLPRI);
5216 client_proto_version[pfdcount] = last_client_proto_version;
5217 type[pfdcount++] = 1;
5218 }
5219
5220 if(demux[i].program_number == 0) { continue; } // only evalutate demuxers that have channels assigned
5221
5222 uint32_t ecmcounter = 0, emmcounter = 0;
5223 for(g = 0; g < maxfilter; g++)
5224 {
5225 if(demux[i].demux_fd[g].fd <= 0) continue; // deny obvious invalid fd!
5226
5227 if(!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX && selected_api != STAPI && selected_api != COOLAPI)
5228 {
5229 pfd2[pfdcount].fd = demux[i].demux_fd[g].fd;
5230 pfd2[pfdcount].events = (POLLIN | POLLPRI);
5231 ids[pfdcount] = i;
5232 fdn[pfdcount] = g;
5233 type[pfdcount++] = 0;
5234 }
5235 if(demux[i].demux_fd[g].type == TYPE_ECM) { ecmcounter++; } // count ecm filters to see if demuxing is possible anyway
5236 if(demux[i].demux_fd[g].type == TYPE_EMM) { emmcounter++; } // count emm filters also
5237 }
5238 if(ecmcounter != demux[i].old_ecmfiltercount || emmcounter != demux[i].old_emmfiltercount) // only produce log if something changed
5239 {
5240 cs_log_dbg(D_DVBAPI, "Demuxer %d has %d ecmpids, %d streampids, %d ecmfilters and %d of max %d emmfilters", i, demux[i].ECMpidcount,
5241 demux[i].STREAMpidcount, ecmcounter, emmcounter, demux[i].max_emm_filter);
5242 demux[i].old_ecmfiltercount = ecmcounter; // save new amount of ecmfilters
5243 demux[i].old_emmfiltercount = emmcounter; // save new amount of emmfilters
5244 }
5245
5246 // delayed emm start for non irdeto caids, start emm cat if not already done for this demuxer!
5247
5248 struct timeb now;
5249 cs_ftime(&now);
5250 int64_t gone;
5251 int8_t do_emm_start = (cfg.dvbapi_au > 0 && demux[i].emm_filter == -1 && demux[i].EMMpidcount == 0 && emmcounter == 0);
5252 int8_t do_sdt_start = (cfg.dvbapi_read_sdt && demux[i].sdt_filter == -1 && cfg.dvbapi_boxtype != BOXTYPE_SAMYGO);
5253
5254 if(do_emm_start || do_sdt_start)
5255 {
5256 gone = comp_timeb(&now, &demux[i].emmstart);
5257
5258 if(gone > 30*1000){
5259
5260 if(do_emm_start) {
5261 cs_ftime(&demux[i].emmstart); // trick to let emm fetching start after 30 seconds to speed up zapping
5262 dvbapi_start_filter(i, demux[i].pidindex, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM); //CAT
5263 }
5264 }
5265
5266 if(gone > 10*1000){
5267 if(do_sdt_start)
5268 {
5269 dvbapi_start_sdt_filter(i);
5270 }
5271 }
5272 }
5273
5274 //early start for irdeto since they need emm before ecm (pmt emmstart = 1 if detected caid 0x06)
5275 int32_t emmstarted = demux[i].emm_filter;
5276 if(cfg.dvbapi_au && demux[i].EMMpidcount > 0) // check every time since share readers might give us new filters due to hexserial change
5277 {
5278 if(!emmcounter && emmstarted == -1)
5279 {
5280 demux[i].emmstart = now;
5281 dvbapi_start_emm_filter(i); // start emmfiltering if emmpids are found
5282 }
5283 else
5284 {
5285 gone = comp_timeb(&now, &demux[i].emmstart);
5286 if(gone > 30*1000)
5287 {
5288 demux[i].emmstart = now;
5289 dvbapi_start_emm_filter(i); // start emmfiltering delayed if filters already were running
5290 rotate_emmfilter(i); // rotate active emmfilters
5291 }
5292 }
5293 }
5294
5295 if(ecmcounter == 0 && demux[i].ECMpidcount > 0) // Restart decoding all caids we have ecmpids but no ecm filters!
5296 {
5297
5298 int32_t started = 0;
5299
5300 for(g = 0; g < demux[i].ECMpidcount; g++) // avoid race: not all pids are asked and checked out yet!
5301 {
5302 if(demux[i].ECMpids[g].checked == 0 && demux[i].ECMpids[g].status >= 0) // check if prio run is done
5303 {
5304 dvbapi_try_next_caid(i, 0); // not done, so start next prio pid
5305 started = 1;
5306 break;
5307 }
5308 }
5309 if(started) { continue; } // if started a filter proceed with next demuxer
5310
5311 if(g == demux[i].ECMpidcount) // all usable pids (with prio) are tried, lets start over again without prio!
5312 {
5313 for(g = 0; g < demux[i].ECMpidcount; g++) // avoid race: not all pids are asked and checked out yet!
5314 {
5315 if(demux[i].ECMpids[g].checked == 2 && demux[i].ECMpids[g].status >= 0) // check if noprio run is done
5316 {
5317 demux[i].ECMpids[g].irdeto_curindex = 0xFE;
5318 demux[i].ECMpids[g].irdeto_maxindex = 0;
5319 demux[i].ECMpids[g].irdeto_cycle = 0xFE;
5320 demux[i].ECMpids[g].tries = 0xFE;
5321 demux[i].ECMpids[g].table = 0;
5322 demux[i].ECMpids[g].CHID = 0x10000; // remove chid prio
5323 dvbapi_try_next_caid(i, 2); // not done, so start next no prio pid
5324 started = 1;
5325 break;
5326 }
5327 }
5328 }
5329 if(started) { continue; } // if started a filter proceed with next demuxer
5330
5331 if(g == demux[i].ECMpidcount) // all usable pids are tried, lets start over again!
5332 {
5333 if(demux[i].decodingtries == -1) // first redecoding attempt?
5334 {
5335 cs_ftime(&demux[i].decstart);
5336 for(g = 0; g < demux[i].ECMpidcount; g++) // reinit some used things from second run (without prio)
5337 {
5338 demux[i].ECMpids[g].checked = 0;
5339 demux[i].ECMpids[g].irdeto_curindex = 0xFE;
5340 demux[i].ECMpids[g].irdeto_maxindex = 0;
5341 demux[i].ECMpids[g].irdeto_cycle = 0xFE;
5342 demux[i].ECMpids[g].table = 0;
5343 demux[i].decodingtries = 0;
5344 dvbapi_edit_channel_cache(i, g, 0); // remove this pid from channelcache since we had no founds on any ecmpid!
5345 }
5346 }
5347 uint8_t number_of_enabled_pids = 0;
5348 demux[i].decodingtries++;
5349 dvbapi_resort_ecmpids(i);
5350
5351 for(g = 0; g < demux[i].ECMpidcount; g++) // count number of enabled pids!
5352 {
5353 if(demux[i].ECMpids[g].status >= 0) number_of_enabled_pids++;
5354 }
5355 if(!number_of_enabled_pids)
5356 {
5357 if(demux[i].decodingtries == 10)
5358 {
5359 demux[i].decodingtries = 0;
5360 cs_log("Demuxer %d no enabled matching ecmpids -> decoding is waiting for matching readers!",i);
5361 }
5362 }
5363 else
5364 {
5365 cs_ftime(&demux[i].decend);
5366 demux[i].decodingtries = -1; // reset to first run again!
5367 gone = comp_timeb(&demux[i].decend, &demux[i].decstart);
5368 cs_log("Demuxer %d restarting decodingrequests after %"PRId64" ms with %d enabled and %d disabled ecmpids!", i, gone, number_of_enabled_pids,
5369 (demux[i].ECMpidcount-number_of_enabled_pids));
5370 dvbapi_try_next_caid(i, 0);
5371 }
5372 }
5373 }
5374
5375 if(demux[i].socket_fd > 0 && cfg.dvbapi_pmtmode != 6)
5376 {
5377 rc = 0;
5378 for(j = 0; j < pfdcount; j++)
5379 {
5380 if(pfd2[j].fd == demux[i].socket_fd)
5381 {
5382 rc = 1;
5383 break;
5384 }
5385 }
5386 if(rc == 1) { continue; }
5387
5388 pfd2[pfdcount].fd = demux[i].socket_fd;
5389 pfd2[pfdcount].events = (POLLIN | POLLPRI);
5390 ids[pfdcount] = i;
5391 type[pfdcount++] = 1;
5392 }
5393 }
5394
5395 rc = 0;
5396 while(!(listenfd == -1 && cfg.dvbapi_pmtmode == 6))
5397 {
5398 rc = poll(pfd2, pfdcount, 500);
5399 if(rc < 0) // error occured while polling for fd's with fresh data
5400 {
5401 if(errno == EINTR || errno == EAGAIN) // try again in case of interrupt
5402 {
5403 continue;
5404 }
5405 cs_log("ERROR: error on poll of %d fd's (errno=%d %s)", pfdcount, errno, strerror(errno));
5406 break;
5407 }
5408 else
5409 {
5410 break;
5411 }
5412 }
5413
5414 if(rc > 0)
5415 {
5416 cs_ftime(&end); // register end time
5417 int64_t timeout = comp_timeb(&end, &start);
5418 if (timeout < 0) {
5419 cs_log("*** WARNING: BAD TIME AFFECTING WHOLE OSCAM ECM HANDLING ****");
5420 }
5421 cs_log_dbg(D_TRACE, "New events occurred on %d of %d handlers after %"PRId64" ms inactivity", rc, pfdcount, timeout);
5422 cs_ftime(&start); // register new start time for next poll
5423 }
5424
5425 for(i = 0; i < pfdcount && rc > 0; i++)
5426 {
5427 if(pfd2[i].revents == 0) { continue; } // skip sockets with no changes
5428 rc--; //event handled!
5429 cs_log_dbg(D_TRACE, "Now handling fd %d that reported event %d", pfd2[i].fd, pfd2[i].revents);
5430
5431 if(pfd2[i].revents & (POLLHUP | POLLNVAL | POLLERR))
5432 {
5433 if(type[i] == 1)
5434 {
5435 for(j = 0; j < MAX_DEMUX; j++)
5436 {
5437 if(demux[j].socket_fd == pfd2[i].fd) // if listenfd closes stop all assigned decoding!
5438 {
5439 dvbapi_stop_descrambling(j);
5440 }
5441
5442 // remove from unassoc_fd when necessary
5443 if (unassoc_fd[j] == pfd2[i].fd)
5444 {
5445 unassoc_fd[j] = 0;
5446 }
5447 }
5448 int32_t ret = close(pfd2[i].fd);
5449 if(ret < 0 && errno != 9) { cs_log("ERROR: Could not close demuxer socket fd (errno=%d %s)", errno, strerror(errno)); }
5450 if(pfd2[i].fd == listenfd && cfg.dvbapi_pmtmode == 6)
5451 {
5452 listenfd = -1;
5453 }
5454
5455 cs_log_dbg(D_DVBAPI, "Socket %d reported hard connection close", pfd2[i].fd);
5456 }
5457 else // type = 0
5458 {
5459 int32_t demux_index = ids[i];
5460 int32_t n = fdn[i];
5461
5462 if(cfg.dvbapi_boxtype != BOXTYPE_SAMYGO)
5463 {
5464 dvbapi_stop_filternum(demux_index, n); // stop filter since its giving errors and wont return anything good.
5465 }
5466 else
5467 {
5468 int32_t ret, pid;
5469 uchar filter[32];
5470 struct dmx_sct_filter_params sFP;
5471
5472 cs_log_dbg(D_DVBAPI, "re-opening connection to demux socket");
5473 close(demux[demux_index].demux_fd[n].fd);
5474 demux[demux_index].demux_fd[n].fd = -1;
5475
5476 ret = dvbapi_open_device(0, demux[demux_index].demux_index, demux[demux_index].adapter_index);
5477 if(ret != -1)
5478 {
5479 demux[demux_index].demux_fd[n].fd = ret;
5480
5481 pid = demux[demux_index].curindex;
5482
5483 memset(filter, 0, 32);
5484 memset(&sFP, 0, sizeof(sFP));
5485
5486 filter[0] = 0x80;
5487 filter[16] = 0xF0;
5488
5489 sFP.pid = demux[demux_index].ECMpids[pid].ECM_PID;
5490 sFP.timeout = 3000;
5491 sFP.flags = DMX_IMMEDIATE_START;
5492 memcpy(sFP.filter.filter, filter, 16);
5493 memcpy(sFP.filter.mask, filter + 16, 16);
5494 ret = dvbapi_ioctl(demux[demux_index].demux_fd[n].fd, DMX_SET_FILTER, &sFP);
5495 }
5496
5497 if(ret == -1)
5498 dvbapi_stop_filternum(demux_index, n); // stop filter since its giving errors and wont return anything good.
5499 }
5500 }
5501 continue; // continue with other events
5502 }
5503
5504 if(pfd2[i].revents & (POLLIN | POLLPRI))
5505 {
5506 if(type[i] == 1)
5507 {
5508 connfd = -1; // initially no socket to read from
5509 uint8_t add_to_poll = 0; // we may need to additionally poll this socket when no PMT data comes in
5510
5511 if (pfd2[i].fd == listenfd)
5512 {
5513 if (cfg.dvbapi_pmtmode == 6) {
5514 connfd = listenfd;
5515 disable_pmt_files = 1;
5516 } else {
5517 clilen = sizeof(servaddr);
5518 connfd = accept(listenfd, (struct sockaddr *)&servaddr, (socklen_t *)&clilen);
5519 cs_log_dbg(D_DVBAPI, "new socket connection fd: %d", connfd);
5520 if (cfg.dvbapi_listenport)
5521 {
5522 //update webif data
5523 client->ip = SIN_GET_ADDR(servaddr);
5524 client->port = ntohs(SIN_GET_PORT(servaddr));
5525 }
5526 add_to_poll = 1;
5527
5528 if(cfg.dvbapi_pmtmode == 3 || cfg.dvbapi_pmtmode == 0) { disable_pmt_files = 1; }
5529
5530 if(connfd <= 0)
5531 cs_log_dbg(D_DVBAPI, "accept() returns error on fd event %d (errno=%d %s)", pfd2[i].revents, errno, strerror(errno));
5532 }
5533 }
5534 else
5535 {
5536 connfd = pfd2[i].fd;
5537 }
5538
5539 //reading and completing data from socket
5540 if (connfd > 0) {
5541
5542 if(unhandled_buf_used[i])
5543 {
5544 memcpy(mbuf, unhandled_buf[i], unhandled_buf_used[i]);
5545 }
5546
5547 if(!dvbapi_handlesockdata(connfd, mbuf, mbuf_size, unhandled_buf_used[i], &add_to_poll, &unhandled_buf_used[i], &client_proto_version[i]))
5548 {
5549 unhandled_buf_used[i] = 0;
5550
5551 //client disconnects, stop all assigned decoding
5552 cs_log_dbg(D_DVBAPI, "Socket %d reported connection close", connfd);
5553 int active_conn = 0; //other active connections counter
5554 add_to_poll = 0;
5555
5556 for (j = 0; j < MAX_DEMUX; j++)
5557 {
5558 if (demux[j].socket_fd == connfd)
5559 {
5560 dvbapi_stop_descrambling(j);
5561 }
5562 else if (demux[j].socket_fd)
5563 {
5564 active_conn++;
5565 }
5566
5567 // remove from unassoc_fd when necessary
5568 if (unassoc_fd[j] == connfd)
5569 {
5570 unassoc_fd[j] = 0;
5571 }
5572 }
5573
5574 close(connfd);
5575 connfd = -1;
5576
5577 if (!active_conn && (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)) //last connection closed
5578 {
5579 if (cfg.dvbapi_listenport)
5580 {
5581 //update webif data
5582 client->ip = get_null_ip();
5583 client->port = 0;
5584 }
5585 }
5586
5587 continue;
5588 }
5589
5590 if(unhandled_buf_used[i])
5591 {
5592 if(unhandled_buf_used[i] > unhandled_buf_len[i])
5593 {
5594 NULLFREE(unhandled_buf[i]);
5595
5596 unhandled_buf_len[i] = unhandled_buf_used[i] < 128 ? 128 : unhandled_buf_used[i];
5597
5598 if(!cs_malloc(&unhandled_buf[i], sizeof(uchar)*unhandled_buf_len[i]))
5599 {
5600 unhandled_buf_len[i] = 0;
5601 unhandled_buf_used[i] = 0;
5602 continue;
5603 }
5604 }
5605
5606 memcpy(unhandled_buf[i], mbuf, unhandled_buf_used[i]);
5607 }
5608
5609 // if the connection is new and we read no PMT data, then add it to the poll,
5610 // otherwise this socket will not be checked with poll when data arives
5611 // because fd it is not yet assigned with the demux
5612 if (add_to_poll) {
5613 for (j = 0; j < MAX_DEMUX; j++) {
5614 if (!unassoc_fd[j]) {
5615 unassoc_fd[j] = connfd;
5616 break;
5617 }
5618 }
5619 }
5620 }
5621 }
5622 else // type==0
5623 {
5624 int32_t demux_index = ids[i];
5625 int32_t n = fdn[i];
5626
5627 if((int)demux[demux_index].demux_fd[n].fd != pfd2[i].fd) { continue; } // filter already killed, no need to process this data!
5628
5629 len = dvbapi_read_device(pfd2[i].fd, mbuf, mbuf_size);
5630 if(len < 0) // serious filterdata read error
5631 {
5632 dvbapi_stop_filternum(demux_index, n); // stop filter since its giving errors and wont return anything good.
5633 maxfilter--; // lower maxfilters to avoid this with new filter setups!
5634 continue;
5635 }
5636 if(!len) // receiver internal filterbuffer overflow
5637 {
5638 memset(mbuf, 0, mbuf_size);
5639 }
5640
5641 dvbapi_process_input(demux_index, n, mbuf, len);
5642 }
5643 continue; // continue with other events!
5644 }
5645 }
5646 }
5647
5648 for(j = 0; j < maxpfdsize; j++)
5649 {
5650 NULLFREE(unhandled_buf[j]);
5651 }
5652 free(mbuf);
5653 return NULL;
5654}
5655
5656void dvbapi_write_cw(int32_t demux_id, uchar *cw, int32_t pid, int32_t stream_id, enum ca_descr_algo algo, enum ca_descr_cipher_mode cipher_mode)
5657{
5658 int32_t n;
5659 int8_t cwEmpty = 0;
5660 unsigned char nullcw[8];
5661 memset(nullcw, 0, 8);
5662 ca_descr_t ca_descr;
5663 ca_descr_mode_t ca_descr_mode;
5664
5665 memset(&ca_descr, 0, sizeof(ca_descr));
5666 memset(&ca_descr_mode, 0, sizeof(ca_descr_mode_t));
5667
5668 if(memcmp(demux[demux_id].lastcw[0], nullcw, 8) == 0
5669 && memcmp(demux[demux_id].lastcw[1], nullcw, 8) == 0)
5670 { cwEmpty = 1; } // to make sure that both cws get written on constantcw
5671
5672
5673 for(n = 0; n < 2; n++)
5674 {
5675 char lastcw[9 * 3];
5676 char newcw[9 * 3];
5677 cs_hexdump(0, demux[demux_id].lastcw[n], 8, lastcw, sizeof(lastcw));
5678 cs_hexdump(0, cw + (n * 8), 8, newcw, sizeof(newcw));
5679
5680 if((memcmp(cw + (n * 8), demux[demux_id].lastcw[n], 8) != 0 || cwEmpty)
5681 && memcmp(cw + (n * 8), nullcw, 8) != 0) // check if already delivered and new cw part is valid!
5682 {
5683 ca_index_t idx = dvbapi_ca_setpid(demux_id, pid, stream_id, (algo == CA_ALGO_DES)); // prepare ca
5684 if (idx == INDEX_INVALID) return; // return on no index!
5685
5686#if defined WITH_COOLAPI || defined WITH_COOLAPI2
5687 ca_descr.index = idx;
5688 ca_descr.parity = n;
5689 memcpy(demux[demux_id].lastcw[n], cw + (n * 8), 8);
5690 memcpy(ca_descr.cw, cw + (n * 8), 8);
5691 cs_log_dbg(D_DVBAPI, "Demuxer %d write cw%d index: %d (ca_mask %d)", demux_id, n, ca_descr.index, demux[demux_id].ca_mask);
5692 coolapi_write_cw(demux[demux_id].ca_mask, demux[demux_id].STREAMpids, demux[demux_id].STREAMpidcount, &ca_descr);
5693#else
5694 int32_t i, j, write_cw = 0;
5695 ca_index_t usedidx, lastidx;
5696
5697 for(i = 0; i < MAX_DEMUX; i++)
5698 {
5699 if(!(demux[demux_id].ca_mask & (1 << i))) continue; // ca not in use by this demuxer!
5700
5701 lastidx = INDEX_INVALID;
5702
5703 for(j = 0; j < demux[demux_id].STREAMpidcount; j++)
5704 {
5705 write_cw = 0;
5706 if(!demux[demux_id].ECMpids[pid].streams || ((demux[demux_id].ECMpids[pid].streams & (1 << j)) == (uint) (1 << j)))
5707 {
5708 usedidx = is_ca_used(i, demux[demux_id].STREAMpids[j]);
5709 if(usedidx != INDEX_INVALID)
5710 {
5711 if(idx != usedidx)
5712 {
5713 cs_log_dbg(D_DVBAPI,"Demuxer %d ca%d is using index %d for streampid %04X -> skip!", demux_id, i, usedidx, demux[demux_id].STREAMpids[j]);
5714 continue; // if not used for descrambling -> skip!
5715 }
5716 else
5717 {
5718 if(usedidx == lastidx)
5719 {
5720 cs_log_dbg(D_DVBAPI,"Demuxer %d ca%d is using index %d for streampid %04X -> skip, %s part of cw already written!",
5721 demux_id, i, usedidx, demux[demux_id].STREAMpids[j], (n == 1 ? "even" : "odd"));
5722 continue;
5723 }
5724 cs_log_dbg(D_DVBAPI,"Demuxer %d ca%d is using index %d for streampid %04X -> write %s part of cw!",
5725 demux_id, i, usedidx, demux[demux_id].STREAMpids[j], (n == 1 ? "even" : "odd"));
5726 write_cw = 1;
5727 }
5728 }
5729 }
5730 if(!write_cw) { continue; } // no need to write the cw since this ca isnt using it!
5731
5732 lastidx = usedidx;
5733 ca_descr.index = usedidx;
5734 ca_descr.parity = n;
5735 memcpy(demux[demux_id].lastcw[n], cw + (n * 8), 8);
5736 memcpy(ca_descr.cw, cw + (n * 8), 8);
5737 cs_log_dbg(D_DVBAPI, "Demuxer %d writing %s part (%s) of controlword, replacing expired (%s)", demux_id, (n == 1 ? "even" : "odd"), newcw, lastcw);
5738 cs_log_dbg(D_DVBAPI, "Demuxer %d write cw%d index: %d (ca%d)", demux_id, n, ca_descr.index, i);
5739
5740 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
5741 dvbapi_net_send(DVBAPI_CA_SET_DESCR, demux[demux_id].socket_fd, demux_id, -1 /*unused*/, (unsigned char *) &ca_descr, NULL, NULL, demux[demux_id].client_proto_version);
5742 else
5743 {
5744 if(ca_fd[i] <= 0)
5745 {
5746 ca_fd[i] = dvbapi_open_device(1, i, demux[demux_id].adapter_index);
5747 if(ca_fd[i] <= 0) { continue; }
5748 }
5749 if (dvbapi_ioctl(ca_fd[i], CA_SET_DESCR, &ca_descr) < 0)
5750 {
5751 cs_log("ERROR: ioctl(CA_SET_DESCR): %s", strerror(errno));
5752 }
5753 }
5754
5755 if(cfg.dvbapi_extended_cw_api == 1)
5756 {
5757 ca_descr_mode.index = usedidx;
5758 ca_descr_mode.algo = algo;
5759 ca_descr_mode.cipher_mode = cipher_mode;
5760
5761 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
5762 dvbapi_net_send(DVBAPI_CA_SET_DESCR_MODE, demux[demux_id].socket_fd, demux_id, -1 /*unused*/, (unsigned char *) &ca_descr_mode, NULL, NULL, demux[demux_id].client_proto_version);
5763 else
5764 {
5765 if(ca_fd[i] <= 0)
5766 {
5767 ca_fd[i] = dvbapi_open_device(1, i, demux[demux_id].adapter_index);
5768 if(ca_fd[i] <= 0) { continue; }
5769 }
5770 if (dvbapi_ioctl(ca_fd[i], CA_SET_DESCR_MODE, &ca_descr_mode) < 0)
5771 {
5772 cs_log("ERROR: ioctl(CA_SET_DESCR_MODE): %s", strerror(errno));
5773 }
5774 }
5775 }
5776 }
5777 }
5778#endif
5779 }
5780 }
5781}
5782
5783void delayer(ECM_REQUEST *er, uint32_t delay)
5784{
5785 if(delay <= 0) { return; }
5786
5787 struct timeb tpe;
5788 cs_ftime(&tpe);
5789 int64_t gone = comp_timeb(&tpe, &er->tps);
5790 if( gone < delay)
5791 {
5792 cs_log_dbg(D_DVBAPI, "delayer: gone=%"PRId64" ms, cfg=%d ms -> delay=%"PRId64" ms", gone, delay, delay - gone);
5793 cs_sleepms(delay - gone);
5794 }
5795}
5796
5797void dvbapi_send_dcw(struct s_client *client, ECM_REQUEST *er)
5798{
5799 int32_t i, j, k, handled = 0;
5800
5801 for(i = 0; i < MAX_DEMUX; i++)
5802 {
5803 uint32_t nocw_write = 0; // 0 = write cw, 1 = dont write cw to hardware demuxer
5804 if(demux[i].program_number == 0) { continue; } // ignore empty demuxers
5805 if(demux[i].program_number != er->srvid) { continue; } // skip ecm response for other srvid
5806
5807#ifdef WITH_STAPI5
5808 if(strcmp(dev_list[demux[i].dev_index].name, er->dev_name) != 0) { continue; } // skip request if PTI device doesn't match request
5809#endif
5810
5811 demux[i].rdr = er->selected_reader;
5812 for(j = 0; j < demux[i].ECMpidcount; j++) // check for matching ecmpid
5813 {
5814 if((demux[i].ECMpids[j].CAID == er->caid || demux[i].ECMpids[j].CAID == er->ocaid)
5815 && demux[i].ECMpids[j].ECM_PID == er->pid
5816 && demux[i].ECMpids[j].PROVID == er->prid
5817 && demux[i].ECMpids[j].VPID == er->vpid)
5818 { break; }
5819 }
5820 if(j == demux[i].ECMpidcount) { continue; } // ecm response srvid ok but no matching ecmpid, perhaps this for other demuxer
5821
5822 cs_log_dbg(D_DVBAPI, "Demuxer %d %scontrolword received for PID %d CAID %04X PROVID %06X ECMPID %04X CHID %04X VPID %04X", i,
5823 (er->rc >= E_NOTFOUND ? "no " : ""), j, er->caid, er->prid, er->pid, er->chid, er->vpid);
5824
5825 uint32_t status = dvbapi_check_ecm_delayed_delivery(i, er);
5826
5827 uint32_t comparecw0 = 0, comparecw1 = 0;
5828 char ecmd5[17 * 3];
5829 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
5830
5831 if(status == 1 && er->rc) // wrong ecmhash
5832 {
5833 cs_log_dbg(D_DVBAPI, "Demuxer %d not interested in response ecmhash %s (requested different one)", i, ecmd5);
5834 continue;
5835 }
5836 if(status == 2) // no filter
5837 {
5838 cs_log_dbg(D_DVBAPI, "Demuxer %d not interested in response ecmhash %s (filter already killed)", i, ecmd5);
5839 continue;
5840 }
5841 if(status == 5) // empty cw
5842 {
5843 cs_log_dbg(D_DVBAPI, "Demuxer %d not interested in response ecmhash %s (delivered cw is empty!)", i, ecmd5);
5844 nocw_write = 1;
5845 if(er->rc < E_NOTFOUND) { er->rc = E_NOTFOUND; }
5846 }
5847
5848 if((status == 0 || status == 3 || status == 4) && er->rc < E_NOTFOUND) // 0=matching ecm hash, 2=no filter, 3=table reset, 4=cache-ex response
5849 {
5850 if(memcmp(er->cw, demux[i].lastcw[0], 8) == 0 && memcmp(er->cw + 8, demux[i].lastcw[1], 8) == 0) // check for matching controlword
5851 {
5852 comparecw0 = 1;
5853 }
5854 else if(memcmp(er->cw, demux[i].lastcw[1], 8) == 0 && memcmp(er->cw + 8, demux[i].lastcw[0], 8) == 0) // check for matching controlword
5855 {
5856 comparecw1 = 1;
5857 }
5858 if(comparecw0 == 1 || comparecw1 == 1)
5859 {
5860 cs_log_dbg(D_DVBAPI, "Demuxer %d duplicate controlword ecm response hash %s (duplicate controlword!)", i, ecmd5);
5861 nocw_write = 1;
5862 }
5863 }
5864
5865 if(status == 3) // table reset
5866 {
5867 cs_log_dbg(D_DVBAPI, "Demuxer %d luckyshot new controlword ecm response hash %s (ecm table reset)", i, ecmd5);
5868 }
5869
5870 if(status == 4) // no check on cache-ex responses!
5871 {
5872 cs_log_dbg(D_DVBAPI, "Demuxer %d new controlword from cache-ex reader (no ecmhash check possible)", i);
5873 }
5874
5875 handled = 1; // mark this ecm response as handled
5876 if(er->rc < E_NOTFOUND && cfg.dvbapi_requestmode == 0 && (demux[i].pidindex == -1) && er->caid != 0)
5877 {
5878 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry flag
5879 demux[i].ECMpids[j].irdeto_cycle = 0xFE; // reset irdetocycle
5880 demux[i].pidindex = j; // set current index as *the* pid to descramble
5881 demux[i].ECMpids[j].checked = 4;
5882 cs_log_dbg(D_DVBAPI, "Demuxer %d descrambling PID %d CAID %04X PROVID %06X ECMPID %04X CHID %02X VPID %04X",
5883 i, demux[i].pidindex, er->caid, er->prid, er->pid, er->chid, er->vpid);
5884 }
5885
5886 if(er->rc < E_NOTFOUND && cfg.dvbapi_requestmode == 1 && er->caid != 0) // FOUND
5887 {
5888 SAFE_MUTEX_LOCK(&demux[i].answerlock); // only process one ecm answer
5889 if(demux[i].ECMpids[j].checked != 4)
5890 {
5891
5892 int32_t t, o, ecmcounter = 0;
5893 int32_t oldpidindex = demux[i].pidindex;
5894 demux[i].pidindex = j; // set current ecmpid as the new pid to descramble
5895 if(oldpidindex != -1)
5896 {
5897 for(k = 0; k < MAX_STREAM_INDICES; k++)
5898 {
5899 demux[i].ECMpids[j].index[k] = demux[i].ECMpids[oldpidindex].index[k]; // swap index with lower status pid that was descrambling
5900 demux[i].ECMpids[j].useMultipleIndices = demux[i].ECMpids[oldpidindex].useMultipleIndices;
5901 }
5902 }
5903
5904 for(t = 0; t < demux[i].ECMpidcount; t++) //check this pid with controlword FOUND for higher status:
5905 {
5906 if(t != j && demux[i].ECMpids[j].status >= demux[i].ECMpids[t].status)
5907 {
5908 for(o = 0; o < maxfilter; o++) // check if ecmfilter is in use & stop all ecmfilters of lower status pids
5909 {
5910 if(demux[i].demux_fd[o].fd > 0 && demux[i].demux_fd[o].type == TYPE_ECM && (demux[i].demux_fd[o].pidindex == t))
5911 {
5912 dvbapi_stop_filternum(i, o); // ecmfilter belongs to lower status pid -> kill!
5913 }
5914 }
5915 dvbapi_edit_channel_cache(i, t, 0); // remove lowerstatus pid from channelcache
5916 demux[i].ECMpids[t].checked = 4; // mark index t as low status
5917 }
5918 }
5919
5920
5921 for(o = 0; o < maxfilter; o++) if(demux[i].demux_fd[o].type == TYPE_ECM) { ecmcounter++; } // count all ecmfilters
5922
5923 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry flag
5924 demux[i].ECMpids[j].irdeto_cycle = 0xFE; // reset irdetocycle
5925
5926 if(ecmcounter == 1) // if total found running ecmfilters is 1 -> we found the "best" pid
5927 {
5928 dvbapi_edit_channel_cache(i, j, 1);
5929 demux[i].ECMpids[j].checked = 4; // mark best pid last ;)
5930 }
5931
5932 cs_log_dbg(D_DVBAPI, "Demuxer %d descrambling PID %d CAID %04X PROVID %06X ECMPID %04X CHID %02X VPID %04X",
5933 i, demux[i].pidindex, er->caid, er->prid, er->pid, er->chid, er->vpid);
5934 }
5935 SAFE_MUTEX_UNLOCK(&demux[i].answerlock); // and release it!
5936 }
5937
5938 if(er->rc >= E_NOTFOUND) // not found on requestmode 0 + 1
5939 {
5940 if(er->rc == E_SLEEPING)
5941 {
5942 dvbapi_stop_descrambling(i);
5943 return;
5944 }
5945
5946 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match(i, j, 'p');
5947
5948 if(forceentry && forceentry->force) // forced pid? keep trying the forced ecmpid!
5949 {
5950 if(!caid_is_irdeto(er->caid) || forceentry->chid < 0x10000) //all cas or irdeto cas with forced prio chid
5951 {
5952 demux[i].ECMpids[j].table = 0;
5953 dvbapi_set_section_filter(i, er, -1);
5954 continue;
5955 }
5956 else // irdeto cas without chid prio forced
5957 {
5958 if(demux[i].ECMpids[j].irdeto_curindex == 0xFE) { demux[i].ECMpids[j].irdeto_curindex = 0x00; } // init irdeto current index to first one
5959 if(!(demux[i].ECMpids[j].irdeto_curindex + 1 > demux[i].ECMpids[j].irdeto_maxindex)) // check for last / max chid
5960 {
5961 cs_log_dbg(D_DVBAPI, "Demuxer %d trying next irdeto chid of FORCED PID %d CAID %04X PROVID %06X ECMPID %04X", i,
5962 j, er->caid, er->prid, er->pid);
5963 demux[i].ECMpids[j].irdeto_curindex++; // irdeto index one up
5964 demux[i].ECMpids[j].table = 0;
5965 dvbapi_set_section_filter(i, er, -1);
5966 continue;
5967 }
5968 }
5969 }
5970
5971 // in case of timeout or fatal LB event give this pid another try but no more than 1 try
5972 if((er->rc == E_TIMEOUT || (er->rcEx && er->rcEx <= E2_CCCAM_NOCARD)) && demux[i].ECMpids[j].tries == 0xFE)
5973 {
5974 demux[i].ECMpids[j].tries-=0x07;
5975 demux[i].ECMpids[j].table = 0;
5976 dvbapi_set_section_filter(i, er, -1);
5977 continue;
5978 }
5979 else // all not found responses exception: first timeout response and first fatal loadbalancer response
5980 {
5981 demux[i].ECMpids[j].CHID = 0x10000; // get rid of this prio chid since it failed!
5982 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry
5983 }
5984
5985 if(caid_is_irdeto(er->caid))
5986 {
5987 if(demux[i].ECMpids[j].irdeto_curindex == 0xFE) { demux[i].ECMpids[j].irdeto_curindex = 0x00; } // init irdeto current index to first one
5988 if(!(demux[i].ECMpids[j].irdeto_curindex + 1 > demux[i].ECMpids[j].irdeto_maxindex)) // check for last / max chid
5989 {
5990 cs_log_dbg(D_DVBAPI, "Demuxer %d trying next irdeto chid of PID %d CAID %04X PROVID %06X ECMPID %04X VPID %04X", i,
5991 j, er->caid, er->prid, er->pid, er->vpid);
5992 demux[i].ECMpids[j].irdeto_curindex++; // irdeto index one up
5993 demux[i].ECMpids[j].table = 0;
5994 dvbapi_set_section_filter(i, er, -1);
5995 continue;
5996 }
5997 }
5998
5999 dvbapi_edit_channel_cache(i, j, 0); // remove this pid from channelcache
6000 if(demux[i].pidindex == j)
6001 {
6002 demux[i].pidindex = -1; // current pid delivered a notfound so this pid isnt being used to descramble any longer-> clear pidindex
6003 }
6004 demux[i].ECMpids[j].irdeto_maxindex = 0;
6005 demux[i].ECMpids[j].irdeto_curindex = 0xFE;
6006 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry flag
6007 demux[i].ECMpids[j].irdeto_cycle = 0xFE; // reset irdetocycle
6008 demux[i].ECMpids[j].table = 0;
6009 demux[i].ECMpids[j].checked = 4; // flag ecmpid as checked
6010 demux[i].ECMpids[j].status = -1; // flag ecmpid as unusable
6011 int32_t found = 1; // setup for first run
6012 int32_t filternum = -1;
6013
6014 while(found > 0) // disable all ecm + emm filters for this notfound
6015 {
6016 found = 0;
6017 filternum = dvbapi_get_filternum(i, er, TYPE_ECM); // get ecm filternumber
6018 if(filternum > -1) // in case valid filter found
6019 {
6020 int32_t fd = demux[i].demux_fd[filternum].fd;
6021 if(fd > 0) // in case valid fd
6022 {
6023 dvbapi_stop_filternum(i, filternum); // stop ecmfilter
6024 found = 1;
6025 }
6026 }
6027 if(caid_is_irdeto(er->caid)) // in case irdeto cas stop old emm filters
6028 {
6029 filternum = dvbapi_get_filternum(i, er, TYPE_EMM); // get emm filternumber
6030 if(filternum > -1) // in case valid filter found
6031 {
6032 int32_t fd = demux[i].demux_fd[filternum].fd;
6033 if(fd > 0) // in case valid fd
6034 {
6035 dvbapi_stop_filternum(i, filternum); // stop emmfilter
6036 found = 1;
6037 }
6038 }
6039 }
6040 }
6041
6042 continue;
6043 }
6044
6045
6046 // below this should be only run in case of ecm answer is found
6047
6048 uint32_t chid = get_subid(er); // derive current chid in case of irdeto, or a unique part of ecm on other cas systems
6049 demux[i].ECMpids[j].CHID = (chid != 0 ? chid : 0x10000); // if not zero apply, otherwise use no chid value 0x10000
6050 dvbapi_edit_channel_cache(i, j, 1); // do it here to here after the right CHID is registered
6051
6052 //dvbapi_set_section_filter(i, er); is not needed anymore (unsure)
6053 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry flag
6054 demux[i].ECMpids[j].irdeto_cycle = 0xFE; // reset irdeto cycle
6055
6056 if(nocw_write || demux[i].pidindex != j) { continue; } // cw was already written by another filter or current pid isnt pid used to descramble so it ends here!
6057
6058 struct s_dvbapi_priority *delayentry = dvbapi_check_prio_match(i, demux[i].pidindex, 'd');
6059 uint32_t delay = 0;
6060
6061 if(delayentry)
6062 {
6063 if(delayentry->delay < 1000)
6064 {
6065 delay = delayentry->delay;
6066 cs_log_dbg(D_DVBAPI, "specific delay: write cw %d ms after ecmrequest", delay);
6067 }
6068 }
6069 else if (cfg.dvbapi_delayer > 0)
6070 {
6071 delay = cfg.dvbapi_delayer;
6072 cs_log_dbg(D_DVBAPI, "generic delay: write cw %d ms after ecmrequest", delay);
6073 }
6074
6075 delayer(er, delay);
6076
6077 switch(selected_api)
6078 {
6079#if defined(WITH_STAPI) || defined(WITH_STAPI5)
6080 case STAPI:
6081 stapi_write_cw(i, er->cw, demux[i].STREAMpids, demux[i].STREAMpidcount, demux[i].pmt_file);
6082 break;
6083#endif
6084 default:
6085 {
6086#ifdef WITH_EXTENDED_CW
6087
6088 if(er->cw_ex.mode != demux[i].ECMpids[j].useMultipleIndices)
6089 {
6090 ca_index_t idx;
6091 for(k = 0; k < demux[i].STREAMpidcount; k++)
6092 {
6093 idx = demux[i].ECMpids[j].useMultipleIndices ? demux[i].ECMpids[j].index[k] : demux[i].ECMpids[j].index[0];
6094 dvbapi_set_pid(i, k, idx, false, false); // disable streampid
6095 }
6096
6097 for(k = 0; k < MAX_STREAM_INDICES; k++)
6098 {
6099 demux[i].ECMpids[j].index[k] = INDEX_INVALID;
6100 }
6101 }
6102
6103 if(er->cw_ex.mode == CW_MODE_MULTIPLE_CW)
6104 {
6105 int32_t key_pos_a = 0;
6106 uint8_t *cw, stream_type;
6107
6108 demux[i].ECMpids[j].useMultipleIndices = 1;
6109
6110 for(k = 0; k < demux[i].STREAMpidcount; k++)
6111 {
6112 stream_type = demux[i].STREAMpidsType[k];
6113
6114 // Video
6115 if(stream_type == 0x01 || stream_type == 0x02 || stream_type == 0x10 || stream_type == 0x1B
6116 || stream_type == 0x24 || stream_type == 0x42 || stream_type == 0x80 || stream_type == 0xD1
6117 || stream_type == 0xEA)
6118 {
6119 cw = er->cw;
6120 }
6121 // Audio
6122 else if(stream_type == 0x03 || stream_type == 0x04 || stream_type == 0x0F || stream_type == 0x11
6123 || stream_type == 0x81 || (stream_type >= 0x83 && stream_type <= 0x87) || stream_type == 0x8A)
6124 {
6125 cw = er->cw_ex.audio[key_pos_a];
6126
6127 if(key_pos_a < 3)
6128 {
6129 key_pos_a++;
6130 }
6131 }
6132 // Data
6133 else
6134 {
6135 cw = er->cw_ex.data;
6136 }
6137
6138 dvbapi_write_cw(i, cw, j, k, er->cw_ex.algo, er->cw_ex.algo_mode);
6139 }
6140 }
6141 else
6142 {
6143 demux[i].ECMpids[j].useMultipleIndices = 0;
6144 dvbapi_write_cw(i, er->cw, j, 0, er->cw_ex.algo, er->cw_ex.algo_mode);
6145 }
6146#else
6147 cfg.dvbapi_extended_cw_api = 0; // in CSA mode extended_cw_api should be always 0 regardless what user selected!
6148 dvbapi_write_cw(i, er->cw, j, 0, CA_ALGO_DVBCSA, CA_MODE_ECB);
6149#endif
6150 break;
6151 }
6152 }
6153
6154 // reset idle-Time
6155 client->last = time((time_t *)0); // ********* TO BE FIXED LATER ON ******
6156
6157 if ((cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX) && demux[i].client_proto_version >= 2)
6158 { dvbapi_net_send(DVBAPI_ECM_INFO, demux[i].socket_fd, i, 0, NULL, client, er, demux[i].client_proto_version); }
6159#ifndef __CYGWIN__
6160 else if (!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX)
6161#endif
6162 if(cfg.dvbapi_boxtype != BOXTYPE_SAMYGO)
6163 { dvbapi_write_ecminfo_file(client, er, demux[i].lastcw[0], demux[i].lastcw[1]); }
6164
6165 }
6166 if(handled == 0)
6167 {
6168 cs_log_dbg(D_DVBAPI, "Unhandled ECM response received for CAID %04X PROVID %06X ECMPID %04X CHID %04X VPID %04X",
6169 er->caid, er->prid, er->pid, er->chid, er->vpid);
6170 }
6171
6172}
6173
6174static int8_t isValidCW(uint8_t *cw)
6175{
6176 uint8_t i;
6177 for(i = 0; i < 16; i += 4)
6178 {
6179 if(((cw[i] + cw[i + 1] + cw[i + 2]) & 0xff) != cw[i + 3])
6180 {
6181 return 0;
6182 }
6183 }
6184 return 1;
6185}
6186
6187void dvbapi_write_ecminfo_file(struct s_client *client, ECM_REQUEST *er, uint8_t* lastcw0, uint8_t* lastcw1)
6188{
6189#define ECMINFO_TYPE_OSCAM 0
6190#define ECMINFO_TYPE_OSCAM_MS 1
6191#define ECMINFO_TYPE_WICARDD 2
6192#define ECMINFO_TYPE_MGCAMD 3
6193#define ECMINFO_TYPE_CCCAM 4
6194#define ECMINFO_TYPE_CAMD3 5
6195
6196 FILE *ecmtxt = fopen(ECMINFO_FILE, "w");
6197 if(ecmtxt != NULL && er->rc < E_NOTFOUND)
6198 {
6199 char tmp[25];
6200 const char *reader_name = NULL, *from_name = NULL, *proto_name = NULL;
6201 int8_t hops = 0;
6202 int32_t from_port = 0;
6203 char system_name[64];
6204 const char* const_system_name = get_cardsystem_desc_by_caid(er->caid);
6205
6206 cs_strncpy(system_name, const_system_name, sizeof(system_name));
6207 system_name[0] = (char)toupper((int)system_name[0]);
6208
6209 if(cfg.dvbapi_ecminfo_type <= ECMINFO_TYPE_WICARDD)
6210 {
6211 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_WICARDD)
6212 {
6213 fprintf(ecmtxt, "system: %s\n", system_name);
6214 }
6215
6216 fprintf(ecmtxt, "caid: 0x%04X\npid: 0x%04X\n", er->caid, er->pid);
6217
6218 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_WICARDD)
6219 {
6220 fprintf(ecmtxt, "prov: %06X\n", (uint) er->prid);
6221 }
6222 else
6223 {
6224 fprintf(ecmtxt, "prov: 0x%06X\n", (uint) er->prid);
6225 }
6226
6227 fprintf(ecmtxt, "chid: 0x%04X\n", er->chid);
6228 }
6229 else if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_MGCAMD)
6230 {
6231 fprintf(ecmtxt, "===== %s ECM on CaID 0x%04X, pid 0x%04X =====\nprov: %06X\n", system_name, er->caid, er->pid, (uint) er->prid);
6232 }
6233 else if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_CCCAM)
6234 {
6235 char provider_name[128];
6236 get_providername(er->prid, er->caid, provider_name, sizeof(provider_name));
6237 if(provider_name[0])
6238 {
6239 fprintf(ecmtxt, "system: %s\ncaid: 0x%04X\nprovider: %s\nprovid: 0x%06X\npid: 0x%04X\n",
6240 system_name, er->caid, provider_name, (uint) er->prid, er->pid);
6241 }
6242 else
6243 {
6244 fprintf(ecmtxt, "system: %s\ncaid: 0x%04X\nprovid: 0x%06X\npid: 0x%04X\n", system_name, er->caid, (uint) er->prid, er->pid);
6245 }
6246 }
6247 else if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_CAMD3)
6248 {
6249 fprintf(ecmtxt, "CAID 0x%04X, PID 0x%04X, PROVIDER 0x%06X\n", er->caid, er->pid, (uint) er->prid);
6250 }
6251
6252 switch(er->rc)
6253 {
6254 case E_FOUND:
6255 if(er->selected_reader)
6256 {
6257 reader_name = er->selected_reader->label;
6258 if(is_network_reader(er->selected_reader))
6259 { from_name = er->selected_reader->device; }
6260 else
6261 { from_name = "local"; }
6262 from_port = er->selected_reader->r_port;
6263 proto_name = reader_get_type_desc(er->selected_reader, 1);
6264 hops = er->selected_reader->currenthops;
6265 }
6266 else
6267 {
6268 reader_name = "none";
6269 from_name = "local";
6270 proto_name = "none";
6271 }
6272 break;
6273
6274 case E_CACHE1:
6275 reader_name = "Cache";
6276 from_name = "cache1";
6277 proto_name = "none";
6278 break;
6279
6280 case E_CACHE2:
6281 reader_name = "Cache";
6282 from_name = "cache2";
6283 proto_name = "none";
6284 break;
6285
6286 case E_CACHEEX:
6287 reader_name = "Cache";
6288 from_name = "cache3";
6289 proto_name = "none";
6290 break;
6291 }
6292
6293
6294 if(cfg.dvbapi_ecminfo_type <= ECMINFO_TYPE_OSCAM_MS)
6295 {
6296 switch(er->rc)
6297 {
6298 case E_FOUND:
6299 if(er->selected_reader)
6300 {
6301 fprintf(ecmtxt, "reader: %s\nfrom: %s\nprotocol: %s\nhops: %d\n", reader_name, from_name, proto_name, hops);
6302 }
6303 break;
6304
6305 case E_CACHE1:
6306 case E_CACHE2:
6307 case E_CACHEEX:
6308 fprintf(ecmtxt, "reader: %s\nfrom: %s\nprotocol: %s\n", reader_name, from_name, proto_name);
6309 break;
6310 }
6311
6312 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_OSCAM)
6313 { fprintf(ecmtxt, "ecm time: %.3f\n", (float) client->cwlastresptime / 1000); }
6314 else
6315 { fprintf(ecmtxt, "ecm time: %d\n", client->cwlastresptime); }
6316 }
6317
6318 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_CAMD3)
6319 {
6320 fprintf(ecmtxt, "FROM: %s\n", reader_name);
6321 fprintf(ecmtxt, "CW0: %s\n", cs_hexdump(1, lastcw0, 8, tmp, sizeof(tmp)));
6322 fprintf(ecmtxt, "CW1: %s\n", cs_hexdump(1, lastcw1, 8, tmp, sizeof(tmp)));
6323 }
6324 else
6325 {
6326 fprintf(ecmtxt, "cw0: %s\n", cs_hexdump(1, lastcw0, 8, tmp, sizeof(tmp)));
6327 fprintf(ecmtxt, "cw1: %s\n", cs_hexdump(1, lastcw1, 8, tmp, sizeof(tmp)));
6328 }
6329
6330 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_WICARDD || cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_MGCAMD)
6331 {
6332 time_t walltime;
6333 struct tm lt;
6334 char timebuf[32];
6335
6336 fprintf(ecmtxt, "Signature %s\n", (isValidCW(lastcw0) || isValidCW(lastcw1)) ? "OK" : "NOK");
6337
6338 if(reader_name != NULL)
6339 {
6340 fprintf(ecmtxt, "source: %s (%s at %s:%d)\n", reader_name, proto_name, from_name, from_port);
6341 }
6342
6343 walltime = cs_time();
6344 localtime_r(&walltime, &lt);
6345
6346 if(strftime(timebuf, 32, "%a %b %d %H:%M:%S %Y", &lt) != 0)
6347 {
6348 fprintf(ecmtxt, "%d msec -- %s\n", client->cwlastresptime, timebuf);
6349 }
6350 }
6351
6352 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_CCCAM)
6353 {
6354 if(reader_name != NULL)
6355 {
6356 fprintf(ecmtxt, "using: %s\naddress: %s:%d\nhops: %d\n", proto_name, from_name, from_port, hops);
6357 }
6358
6359 fprintf(ecmtxt, "ecm time: %d\n", client->cwlastresptime);
6360 }
6361 }
6362
6363 if(ecmtxt)
6364 {
6365 int32_t ret = fclose(ecmtxt);
6366 if(ret < 0) { cs_log("ERROR: Could not close ecmtxt fd (errno=%d %s)", errno, strerror(errno)); }
6367 ecmtxt = NULL;
6368 }
6369}
6370
6371
6372void *dvbapi_start_handler(struct s_client *cl, uchar *UNUSED(mbuf), int32_t module_idx, void * (*_main_func)(void *))
6373{
6374 // cs_log("dvbapi loaded fd=%d", idx);
6375 if(cfg.dvbapi_enabled == 1)
6376 {
6377 cl = create_client(get_null_ip());
6378 cl->module_idx = module_idx;
6379 cl->typ = 'c';
6380 int32_t ret = start_thread("dvbapi handler", _main_func, (void *) cl, &cl->thread, 1, 0);
6381 if(ret)
6382 {
6383 return NULL;
6384 }
6385 }
6386
6387 return NULL;
6388}
6389
6390void *dvbapi_handler(struct s_client *cl, uchar *mbuf, int32_t module_idx)
6391{
6392 return dvbapi_start_handler(cl, mbuf, module_idx, dvbapi_main_local);
6393}
6394
6395int32_t dvbapi_set_section_filter(int32_t demux_index, ECM_REQUEST *er, int32_t n)
6396{
6397 if(!er) { return -1; }
6398
6399 if(USE_OPENXCAS)
6400 {
6401 return 0;
6402 }
6403
6404 if(selected_api != DVBAPI_3 && selected_api != DVBAPI_1 && selected_api != STAPI) // only valid for dvbapi3, dvbapi1 and STAPI
6405 {
6406 return 0;
6407 }
6408
6409 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX || cfg.dvbapi_boxtype == BOXTYPE_IPBOX_PMT) // reported buggy using sectionfiltering after 1~4 hours -> for now disabled!
6410 {
6411 return 0;
6412 }
6413
6414 if(n == -1)
6415 {
6416 n = dvbapi_get_filternum(demux_index, er, TYPE_ECM);
6417 }
6418
6419 if(n < 0) { return -1; } // in case no valid filter found;
6420
6421 int32_t fd = demux[demux_index].demux_fd[n].fd;
6422 if(fd < 1) { return -1 ; } // in case no valid fd
6423
6424 uchar filter[16];
6425 uchar mask[16];
6426 memset(filter, 0, 16);
6427 memset(mask, 0, 16);
6428
6429 struct s_ecmpids *curpid = NULL;
6430 int32_t pid = demux[demux_index].demux_fd[n].pidindex;
6431 if(pid != -1)
6432 {
6433 curpid = &demux[demux_index].ECMpids[pid];
6434 }
6435 if(curpid->table != er->ecm[0] && curpid->table != 0) { return -1; } // if current ecmtype differs from latest requested ecmtype do not apply section filtering!
6436 uint8_t ecmfilter = 0;
6437
6438 if(er->ecm[0] == 0x80) { ecmfilter = 0x81; } // current processed ecm is even, next will be filtered for odd
6439 else { ecmfilter = 0x80; } // current processed ecm is odd, next will be filtered for even
6440
6441 if(curpid->table != 0) // cycle ecmtype from odd to even or even to odd
6442 {
6443 filter[0] = ecmfilter; // only accept new ecms (if previous odd, filter for even and visaversa)
6444 mask[0] = 0xFF;
6445 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set ecmtable to %s (CAID %04X PROVID %06X FD %d)", demux_index, n + 1,
6446 (ecmfilter == 0x80 ? "EVEN" : "ODD"), curpid->CAID, curpid->PROVID, fd);
6447 }
6448 else // not decoding right now so we are interessted in all ecmtypes!
6449 {
6450 filter[0] = 0x80; // set filter to wait for any ecms
6451 mask[0] = 0xF0;
6452 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set ecmtable to ODD+EVEN (CAID %04X PROVID %06X FD %d)", demux_index, n + 1,
6453 curpid->CAID, curpid->PROVID, fd);
6454 }
6455 uint32_t offset = 0, extramask = 0xFF;
6456
6457 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match(demux_index, pid, 'p');
6458 //cs_log("**** curpid->CHID %04X, checked = %d, er->chid = %04X *****", curpid->CHID, curpid->checked, er->chid);
6459 // checked 4 to make sure we dont set chid filter and no such ecm in dvbstream except for forced pids!
6460 if(curpid->CHID < 0x10000 && (curpid->checked == 4 || (forceentry && forceentry->force)))
6461 {
6462
6463 switch(er->caid >> 8)
6464 {
6465 case 0x01:
6466 offset = 7;
6467 extramask = 0xF0;
6468 break; // seca
6469 case 0x05:
6470 offset = 8;
6471 break; // viaccess
6472 case 0x06:
6473 offset = 6;
6474 break; // irdeto
6475 case 0x09:
6476 offset = 11;
6477 break; // videoguard
6478 case 0x4A: // DRE-Crypt, Bulcrypt,Tongang and others?
6479 if(!caid_is_bulcrypt(er->caid))
6480 { offset = 6; }
6481 break;
6482 }
6483 }
6484
6485 int32_t irdetomatch = 1; // check if wanted irdeto index is the one the delivers current chid!
6486 if(caid_is_irdeto(curpid->CAID))
6487 {
6488 if(curpid->irdeto_curindex == er->ecm[4]) { irdetomatch = 1; } // ok apply chid filtering
6489 else { irdetomatch = 0; } // skip chid filtering but apply irdeto index filtering
6490 }
6491
6492 if(offset && irdetomatch) // we have a cas with chid or unique part in checked ecm
6493 {
6494 i2b_buf(2, curpid->CHID, filter + (offset - 2));
6495 mask[(offset - 2)] = 0xFF&extramask; // additional mask seca2 chid can be FC10 or FD10 varies each month so only apply F?10
6496 mask[(offset - 1)] = 0xFF;
6497 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set chid to %04X on fd %d", demux_index, n + 1, curpid->CHID, fd);
6498 }
6499 else
6500 {
6501 if(caid_is_irdeto(curpid->CAID) && (curpid->irdeto_curindex < 0xFE)) // on irdeto we can always apply irdeto index filtering!
6502 {
6503 filter[2] = curpid->irdeto_curindex;
6504 mask[2] = 0xFF;
6505 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set irdetoindex to %d on fd %d", demux_index, n + 1, curpid->irdeto_curindex, fd);
6506 }
6507 else // all other cas systems also cas systems without chid or unique ecm part
6508 {
6509 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set chid to ANY CHID on fd %d", demux_index, n + 1, fd);
6510 }
6511 }
6512
6513 int32_t ret = dvbapi_activate_section_filter(demux_index, n, fd, curpid->ECM_PID, filter, mask);
6514 if(ret < 0) // something went wrong setting filter!
6515 {
6516 cs_log("Demuxer %d Filter %d (fd %d) error setting section filtering -> stop filter!", demux_index, n + 1, fd);
6517 ret = dvbapi_stop_filternum(demux_index, n);
6518 if(ret == -1)
6519 {
6520 cs_log("Demuxer %d Filter %d (fd %d) stopping filter failed -> kill all filters of this demuxer!", demux_index, n + 1, fd);
6521 dvbapi_stop_filter(demux_index, TYPE_EMM);
6522 dvbapi_stop_filter(demux_index, TYPE_ECM);
6523 }
6524 return -1;
6525 }
6526 return n;
6527}
6528
6529int32_t dvbapi_activate_section_filter(int32_t demux_index, int32_t num, int32_t fd, int32_t pid, uchar *filter, uchar *mask)
6530{
6531
6532 int32_t ret = -1;
6533
6534 switch(selected_api)
6535 {
6536 case DVBAPI_3:
6537 {
6538 struct dmx_sct_filter_params sFP2;
6539 memset(&sFP2, 0, sizeof(sFP2));
6540 sFP2.pid = pid;
6541 sFP2.timeout = 0;
6542 sFP2.flags = DMX_IMMEDIATE_START;
6543 if(cfg.dvbapi_boxtype == BOXTYPE_NEUMO)
6544 {
6545 //DeepThought: on dgs/cubestation and neumo images, perhaps others
6546 //the following code is needed to descramble
6547 sFP2.filter.filter[0] = filter[0];
6548 sFP2.filter.mask[0] = mask[0];
6549 sFP2.filter.filter[1] = 0;
6550 sFP2.filter.mask[1] = 0;
6551 sFP2.filter.filter[2] = 0;
6552 sFP2.filter.mask[2] = 0;
6553 memcpy(sFP2.filter.filter + 3, filter + 1, 16 - 3);
6554 memcpy(sFP2.filter.mask + 3, mask + 1, 16 - 3);
6555 //DeepThought: in the drivers of the dgs/cubestation and neumo images,
6556 //dvbapi 1 and 3 are somehow mixed. In the kernel drivers, the DMX_SET_FILTER
6557 //ioctl expects to receive a dmx_sct_filter_params structure (DVBAPI 3) but
6558 //due to a bug its sets the "positive mask" wrongly (they should be all 0).
6559 //On the other hand, the DMX_SET_FILTER1 ioctl also uses the dmx_sct_filter_params
6560 //structure, which is incorrect (it should be dmxSctFilterParams).
6561 //The only way to get it right is to call DMX_SET_FILTER1 with the argument
6562 //expected by DMX_SET_FILTER. Otherwise, the timeout parameter is not passed correctly.
6563 ret = dvbapi_ioctl(fd, DMX_SET_FILTER1, &sFP2);
6564 }
6565 else
6566 {
6567 memcpy(sFP2.filter.filter, filter, 16);
6568 memcpy(sFP2.filter.mask, mask, 16);
6569 if (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
6570 ret = dvbapi_net_send(DVBAPI_DMX_SET_FILTER, demux[demux_index].socket_fd, demux_index, num, (unsigned char *) &sFP2, NULL, NULL, demux[demux_index].client_proto_version);
6571 else
6572 ret = dvbapi_ioctl(fd, DMX_SET_FILTER, &sFP2);
6573 }
6574 break;
6575 }
6576
6577 case DVBAPI_1:
6578 {
6579 struct dmxSctFilterParams sFP1;
6580 memset(&sFP1, 0, sizeof(sFP1));
6581 sFP1.pid = pid;
6582 sFP1.timeout = 0;
6583 sFP1.flags = DMX_IMMEDIATE_START;
6584 memcpy(sFP1.filter.filter, filter, 16);
6585 memcpy(sFP1.filter.mask, mask, 16);
6586 ret = dvbapi_ioctl(fd, DMX_SET_FILTER1, &sFP1);
6587 break;
6588 }
6589#if defined(WITH_STAPI) || defined(WITH_STAPI5)
6590 case STAPI:
6591 {
6592 ret = stapi_activate_section_filter(fd, filter, mask);
6593 break;
6594 }
6595#endif
6596 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
6597 case COOLAPI:
6598 {
6599 int32_t n = coolapi_get_filter_num(fd);
6600 if (n < 0)
6601 return n;
6602 coolapi_set_filter(fd, n, pid, filter, mask, TYPE_ECM);
6603 break;
6604 }
6605 #endif
6606
6607 default:
6608 break;
6609 }
6610 if(ret!=-1) // only change filter/mask for comparing if box returned no errors!
6611 {
6612 memcpy(demux[demux_index].demux_fd[num].filter, filter, 16); // copy filter to check later on if receiver delivered accordingly
6613 memcpy(demux[demux_index].demux_fd[num].mask, mask, 16); // copy mask to check later on if receiver delivered accordingly
6614 }
6615 return ret;
6616}
6617
6618
6619int32_t dvbapi_check_ecm_delayed_delivery(int32_t demux_index, ECM_REQUEST *er)
6620{
6621 int32_t ret = 0;
6622 int32_t filternum = dvbapi_get_filternum(demux_index, er, TYPE_ECM);
6623 char nullcw[CS_ECMSTORESIZE];
6624 memset(nullcw, 0, CS_ECMSTORESIZE);
6625
6626 if(filternum < 0) { return 2; } // if no matching filter act like ecm response is delayed
6627 if(memcmp(demux[demux_index].demux_fd[filternum].lastecmd5, nullcw, CS_ECMSTORESIZE))
6628 {
6629 demux[demux_index].demux_fd[filternum].lastresult = er->rc; // save last result
6630 char ecmd5[17 * 3];
6631 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
6632 cs_log_dbg(D_DVBAPI, "Demuxer %d requested controlword for ecm %s on fd %d", demux_index, ecmd5, demux[demux_index].demux_fd[filternum].fd);
6633 unsigned char md5tmp[MD5_DIGEST_LENGTH];
6634 MD5(er->ecm, er->ecmlen, md5tmp);
6635 ret = (memcmp(demux[demux_index].demux_fd[filternum].lastecmd5, md5tmp, CS_ECMSTORESIZE) !=0 ? 1:0); // 1 = no response on the ecm we request last for this fd!
6636 }
6637
6638 if(memcmp(er->cw, nullcw, 8) == 0 && memcmp(er->cw+8, nullcw, 8) == 0) {return 5;} // received a null cw -> not usable!
6639 struct s_ecmpids *curpid = NULL;
6640
6641 int32_t pid = demux[demux_index].demux_fd[filternum].pidindex;
6642
6643 if(pid !=-1)
6644 {
6645 curpid = &demux[demux_index].ECMpids[pid];
6646 if(curpid->table == 0) { return 3; } // on change table act like ecm response is found
6647 }
6648
6649 if(er->rc == E_CACHEEX) { return 4; } // on cache-ex response act like ecm response is found
6650
6651
6652 return ret;
6653}
6654
6655int32_t dvbapi_get_filternum(int32_t demux_index, ECM_REQUEST *er, int32_t type)
6656{
6657 if(!er) { return -1; }
6658
6659 int32_t n;
6660 int32_t fd = -1;
6661
6662 for(n = 0; n < maxfilter; n++) // determine fd
6663 {
6664 if(demux[demux_index].demux_fd[n].fd > 0 && demux[demux_index].demux_fd[n].type == type) // check for valid and right type (ecm or emm)
6665 {
6666 if(type == TYPE_ECM && er->srvid != demux[demux_index].program_number) continue;
6667 if((demux[demux_index].demux_fd[n].pid == er->pid) &&
6668 ((demux[demux_index].demux_fd[n].provid == er->prid) || demux[demux_index].demux_fd[n].provid == 0 || er->prid == 0) &&
6669 ((demux[demux_index].demux_fd[n].caid == er->caid) || (demux[demux_index].demux_fd[n].caid == er->ocaid))) // current ecm pid?
6670 {
6671 fd = demux[demux_index].demux_fd[n].fd; // found!
6672 if(demux[demux_index].demux_fd[n].caid == er->ocaid)
6673 {
6674 memset(demux[demux_index].demux_fd[n].lastecmd5, 0, CS_ECMSTORESIZE); // clear ecmd5 hash since betatunneled ecms hash different!
6675 }
6676 break;
6677 }
6678 }
6679 }
6680 if(fd > 0 && demux[demux_index].demux_fd[n].provid == 0) { demux[demux_index].demux_fd[n].provid = er->prid; } // hack to fill in provid into demuxer
6681
6682 return (fd > 0 ? n : fd); // return -1(fd) on not found, on found return filternumber(n)
6683}
6684
6685ca_index_t dvbapi_ca_setpid(int32_t demux_index, int32_t pid, int32_t stream_id, bool use_des)
6686{
6687 ca_index_t idx;
6688 int32_t n;
6689
6690 if(pid == -1 || pid > demux[demux_index].ECMpidcount) return INDEX_INVALID;
6691
6692 if(demux[demux_index].ECMpids[pid].useMultipleIndices)
6693 {
6694 n = stream_id;
6695 idx = demux[demux_index].ECMpids[pid].index[n];
6696
6697 if(idx == INDEX_INVALID) // if no indexer for this pid get one!
6698 {
6699 idx = dvbapi_get_descindex(demux_index, pid, n);
6700 if(idx == INDEX_INVALID)
6701 {
6702 cs_log_dbg(D_DVBAPI, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X has no free index", demux_index, pid,
6703 demux[demux_index].ECMpids[pid].CAID, demux[demux_index].ECMpids[pid].ECM_PID);
6704 return INDEX_INVALID;
6705 }
6706
6707 cs_log_dbg(D_DVBAPI, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X is using index %d for stream %d", demux_index, pid,
6708 demux[demux_index].ECMpids[pid].CAID, demux[demux_index].ECMpids[pid].ECM_PID, idx, n);
6709 }
6710
6711 if(!demux[demux_index].ECMpids[pid].streams || ((demux[demux_index].ECMpids[pid].streams & (1 << n)) == (uint) (1 << n)))
6712 {
6713 dvbapi_set_pid(demux_index, n, idx, true, use_des); // enable streampid
6714 }
6715 else
6716 {
6717 dvbapi_set_pid(demux_index, n, idx, false, false); // disable streampid
6718 }
6719 }
6720 else
6721 {
6722 idx = demux[demux_index].ECMpids[pid].index[0];
6723
6724 if(idx == INDEX_INVALID) // if no indexer for this pid get one!
6725 {
6726 idx = dvbapi_get_descindex(demux_index, pid, 0);
6727 if(idx == INDEX_INVALID)
6728 {
6729 cs_log_dbg(D_DVBAPI, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X has no free index", demux_index, pid,
6730 demux[demux_index].ECMpids[pid].CAID, demux[demux_index].ECMpids[pid].ECM_PID);
6731 return INDEX_INVALID;
6732 }
6733
6734 cs_log_dbg(D_DVBAPI, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X is using index %d", demux_index, pid,
6735 demux[demux_index].ECMpids[pid].CAID, demux[demux_index].ECMpids[pid].ECM_PID, idx);
6736 }
6737
6738 for(n = 0; n < demux[demux_index].STREAMpidcount; n++)
6739 {
6740 if(!demux[demux_index].ECMpids[pid].streams || ((demux[demux_index].ECMpids[pid].streams & (1 << n)) == (uint) (1 << n)))
6741 {
6742 dvbapi_set_pid(demux_index, n, idx, true, use_des); // enable streampid
6743 }
6744 else
6745 {
6746 dvbapi_set_pid(demux_index, n, idx, false, false); // disable streampid
6747 }
6748 }
6749 }
6750
6751 return idx; // return caindexer
6752}
6753
6754int8_t update_streampid_list(uint8_t cadevice, uint16_t pid, ca_index_t idx, bool use_des)
6755{
6756 struct s_streampid *listitem, *newlistitem;
6757 LL_ITER itr;
6758
6759 if(!ll_activestreampids)
6760 { ll_activestreampids = ll_create("ll_activestreampids"); }
6761
6762 if(idx > INDEX_MAX)
6763 { return INVALID_STREAMPID_INDEX; }
6764
6765 if(ll_count(ll_activestreampids) > 0)
6766 {
6767 itr = ll_iter_create(ll_activestreampids);
6768 while((listitem = ll_iter_next(&itr)))
6769 {
6770 if (cadevice == listitem->cadevice && pid == listitem->streampid){
6771 if((listitem->activeindexers & (1 << idx)) == (uint64_t) (1 << idx)){
6772
6773 if(cfg.dvbapi_extended_cw_api == 2 && use_des != listitem->use_des)
6774 {
6775 listitem->use_des = use_des;
6776 return FIRST_STREAMPID_INDEX;
6777 }
6778
6779 return FOUND_STREAMPID_INDEX; // match found
6780 }else{
6781 listitem->activeindexers|=(1 << idx); // ca + pid found but not this index -> add this index
6782 cs_log_dbg(D_DVBAPI, "Added existing streampid %04X with new index %d to ca%d", pid, idx, cadevice);
6783
6784 if(cfg.dvbapi_extended_cw_api == 2 && use_des != listitem->use_des)
6785 {
6786 listitem->use_des = use_des;
6787 return FIRST_STREAMPID_INDEX;
6788 }
6789
6790 return ADDED_STREAMPID_INDEX;
6791 }
6792 }
6793 }
6794 }
6795 if(!cs_malloc(&newlistitem, sizeof(struct s_streampid)))
6796 { return FIRST_STREAMPID_INDEX; }
6797 newlistitem->cadevice = cadevice;
6798 newlistitem->streampid = pid;
6799 newlistitem->activeindexers = (1 << idx);
6800 newlistitem->caindex = idx; // set this index as used to decode on ca device
6801 newlistitem->use_des = use_des;
6802 ll_append(ll_activestreampids, newlistitem);
6803 cs_log_dbg(D_DVBAPI, "Added new streampid %04X with index %d to ca%d", pid, idx, cadevice);
6804 return FIRST_STREAMPID_INDEX;
6805}
6806
6807int8_t remove_streampid_from_list(uint8_t cadevice, uint16_t pid, ca_index_t idx)
6808{
6809 struct s_streampid *listitem;
6810 int8_t removed = 0;
6811 LL_ITER itr;
6812
6813 if(!ll_activestreampids)
6814 { return NO_STREAMPID_LISTED; }
6815
6816 if(idx > INDEX_MAX)
6817 { return INVALID_STREAMPID_INDEX; }
6818
6819 if(ll_count(ll_activestreampids) > 0)
6820 {
6821 itr = ll_iter_create(ll_activestreampids);
6822 while((listitem = ll_iter_next(&itr)))
6823 {
6824 if (cadevice == listitem->cadevice && pid == listitem->streampid)
6825 {
6826 if(idx == INDEX_DISABLE_ALL) {
6827 listitem->activeindexers = 0;
6828 removed = 1;
6829 }
6830 else if((listitem->activeindexers & (1 << idx)) == (uint64_t) (1 << idx))
6831 {
6832 listitem->activeindexers &= ~(1 << idx); // flag it as disabled for this index
6833 removed = 1;
6834 }
6835
6836 if(removed)
6837 {
6838 cs_log_dbg(D_DVBAPI, "Remove streampid %04X using indexer %d from ca%d", pid, idx, cadevice);
6839 }
6840 if (listitem->activeindexers == 0 && removed == 1) // all indexers disabled? -> remove pid from list!
6841 {
6842 ll_iter_remove_data(&itr);
6843 cs_log_dbg(D_DVBAPI, "Removed last indexer of streampid %04X from ca%d", pid, cadevice);
6844 return REMOVED_STREAMPID_LASTINDEX;
6845 }
6846 else if(removed == 1)
6847 {
6848 if (idx != INDEX_DISABLE_ALL && idx != listitem->caindex)
6849 {
6850 return REMOVED_STREAMPID_INDEX;
6851 }
6852 else
6853 {
6854 listitem->caindex = INDEX_INVALID;
6855 cs_log_dbg(D_DVBAPI, "Streampid %04X index %d was used for decoding on ca%d", pid, idx, cadevice);
6856 return REMOVED_DECODING_STREAMPID_INDEX;
6857 }
6858 }
6859 return INVALID_STREAMPID_INDEX;
6860 }
6861 }
6862 }
6863 return NO_STREAMPID_LISTED;
6864}
6865
6866void disable_unused_streampids(int16_t demux_id)
6867{
6868 if(selected_api == STAPI) return; // stapi handles pids itself!
6869
6870 if(!ll_activestreampids) return;
6871 if(ll_count(ll_activestreampids) == 0) return; // no items in list?
6872
6873 int32_t ecmpid = demux[demux_id].pidindex;
6874 if (ecmpid == -1) return; // no active ecmpid!
6875
6876 int32_t j;
6877
6878 if(demux[demux_id].ECMpids[ecmpid].useMultipleIndices == 0)
6879 {
6880 ca_index_t idx = demux[demux_id].ECMpids[ecmpid].index[0];
6881 int32_t i,n;
6882 struct s_streampid *listitem;
6883 // search for old enabled streampids on all ca devices that have to be disabled
6884 for(i = 0; i < MAX_DEMUX && idx != INDEX_INVALID; i++)
6885 {
6886 if(!((demux[demux_id].ca_mask & (1 << i)) == (uint32_t) (1 << i))) continue; // continue if ca is unused by this demuxer
6887
6888 LL_ITER itr;
6889 itr = ll_iter_create(ll_activestreampids);
6890 while((listitem = ll_iter_next(&itr)))
6891 {
6892 if (i != listitem->cadevice) continue; // ca doesnt match
6893 if (!((listitem->activeindexers & (1 << (idx))) == (uint64_t) (1 << (idx)))) continue; // index doesnt match
6894 for(n = 0; n < demux[demux_id].STREAMpidcount; n++){
6895 if(demux[demux_id].ECMpidcount == 0) // FTA? -> disable stream!
6896 {
6897 n = demux[demux_id].STREAMpidcount;
6898 break;
6899 }
6900 if (listitem->streampid == demux[demux_id].STREAMpids[n]){ // check if pid matches with current streampid on demuxer
6901 break;
6902 }
6903 }
6904 if (n == demux[demux_id].STREAMpidcount){
6905 demux[demux_id].STREAMpids[n] = listitem->streampid; // put it temp here!
6906 dvbapi_set_pid(demux_id, n, idx, false, false); // no match found so disable this now unused streampid
6907 demux[demux_id].STREAMpids[n] = 0; // remove temp!
6908 }
6909 }
6910
6911 for(n = 0; n < demux[demux_id].STREAMpidcount && demux[demux_id].ECMpidcount != 0; n++) // ECMpidcount != 0 -> skip enabling on fta
6912 {
6913 ll_iter_reset(&itr);
6914 if(!demux[demux_id].ECMpids[ecmpid].streams || ((demux[demux_id].ECMpids[ecmpid].streams & (1 << n)) == (uint) (1 << n)))
6915 {
6916 while((listitem = ll_iter_next(&itr)))
6917 {
6918 if (i != listitem->cadevice) continue; // ca doesnt match
6919 if (!((listitem->activeindexers & (1 << (idx))) == (uint64_t) (1 << (idx)))) continue; // index doesnt match
6920 if (listitem->streampid == demux[demux_id].STREAMpids[n]) // check if pid matches with current streampid on demuxer
6921 {
6922 break;
6923 }
6924 }
6925 if(!listitem) // if streampid not listed -> enable it!
6926 {
6927 dvbapi_set_pid(demux_id, n, idx, true, false); // enable streampid
6928 }
6929 }
6930 }
6931 }
6932 }
6933 else
6934 {
6935 ca_index_t idx = INDEX_INVALID;
6936 int32_t i,n;
6937 uint8_t skip;
6938 struct s_streampid *listitem;
6939 // search for old enabled streampids on all ca devices that have to be disabled
6940 for(i = 0; i < MAX_DEMUX && idx != INDEX_INVALID; i++)
6941 {
6942 if(!((demux[demux_id].ca_mask & (1 << i)) == (uint32_t) (1 << i))) continue; // continue if ca is unused by this demuxer
6943
6944 LL_ITER itr;
6945 itr = ll_iter_create(ll_activestreampids);
6946 while((listitem = ll_iter_next(&itr)))
6947 {
6948 if (i != listitem->cadevice) continue; // ca doesnt match
6949
6950 for(skip = 1, j = 0; j < MAX_STREAM_INDICES; j++)
6951 {
6952 idx = demux[demux_id].ECMpids[ecmpid].index[j];
6953 if(idx == INDEX_INVALID) continue;
6954
6955 if ((listitem->activeindexers & (1 << (idx))) == (uint64_t) (1 << (idx)))
6956 {
6957 skip = 0; // index match
6958 break;
6959 }
6960 }
6961
6962 if(skip) continue;
6963
6964 for(n = 0; n < demux[demux_id].STREAMpidcount; n++){
6965 if(demux[demux_id].ECMpidcount == 0) // FTA? -> disable stream!
6966 {
6967 n = demux[demux_id].STREAMpidcount;
6968 break;
6969 }
6970 if (listitem->streampid == demux[demux_id].STREAMpids[n]){ // check if pid matches with current streampid on demuxer
6971 break;
6972 }
6973 }
6974 if (n == demux[demux_id].STREAMpidcount){
6975 demux[demux_id].STREAMpids[n] = listitem->streampid; // put it temp here!
6976 dvbapi_set_pid(demux_id, n, idx, false, false); // no match found so disable this now unused streampid
6977 demux[demux_id].STREAMpids[n] = 0; // remove temp!
6978 }
6979 }
6980
6981 for(n = 0; n < demux[demux_id].STREAMpidcount && demux[demux_id].ECMpidcount != 0; n++) // ECMpidcount != 0 -> skip enabling on fta
6982 {
6983 ll_iter_reset(&itr);
6984 if(!demux[demux_id].ECMpids[ecmpid].streams || ((demux[demux_id].ECMpids[ecmpid].streams & (1 << n)) == (uint) (1 << n)))
6985 {
6986 while((listitem = ll_iter_next(&itr)))
6987 {
6988 if (i != listitem->cadevice) continue; // ca doesnt match
6989
6990 for(skip = 1, j = 0; j < MAX_STREAM_INDICES; j++)
6991 {
6992 idx = demux[demux_id].ECMpids[ecmpid].index[j];
6993 if(idx == INDEX_INVALID) continue;
6994
6995 if ((listitem->activeindexers & (1 << (idx))) == (uint64_t) (1 << (idx)))
6996 {
6997 skip = 0; // index match
6998 break;
6999 }
7000 }
7001
7002 if(skip) continue;
7003
7004 if (listitem->streampid == demux[demux_id].STREAMpids[n]) // check if pid matches with current streampid on demuxer
7005 {
7006 break;
7007 }
7008 }
7009 if(!listitem) // if streampid not listed -> enable it!
7010 {
7011 dvbapi_set_pid(demux_id, n, idx, true, false); // enable streampid
7012 }
7013 }
7014 }
7015 }
7016 }
7017}
7018
7019
7020ca_index_t is_ca_used(uint8_t cadevice, int32_t pid)
7021{
7022 struct s_streampid *listitem;
7023 LL_ITER itr;
7024
7025 if(!ll_activestreampids)
7026 { return INDEX_INVALID; }
7027
7028 if(ll_count(ll_activestreampids) > 0)
7029 {
7030 itr = ll_iter_create(ll_activestreampids);
7031 while((listitem = ll_iter_next(&itr)))
7032 {
7033 if(listitem->cadevice != cadevice)
7034 { continue; }
7035
7036 if(pid && listitem->streampid != pid)
7037 { continue; }
7038
7039 uint32_t i = 0;
7040 while(listitem->caindex == INDEX_INVALID && i <= INDEX_MAX)
7041 {
7042 if((listitem->activeindexers&(1 << i)) == (uint64_t)(1 << i))
7043 {
7044 listitem->caindex = i; // set fresh one
7045 cs_log_dbg(D_DVBAPI, "Streampid %04X is now using index %d for decoding on ca%d", pid, i, cadevice);
7046 break;
7047 }
7048 i++;
7049 }
7050
7051 if(listitem->caindex == INDEX_INVALID)
7052 {
7053 ll_iter_remove_data(&itr);
7054 return INDEX_INVALID;
7055 }
7056
7057 return listitem->caindex;
7058 }
7059 }
7060 return INDEX_INVALID; // no indexer found for this pid!
7061}
7062
7063uint16_t dvbapi_get_client_proto_version(void)
7064{
7065 return last_client_proto_version;
7066}
7067
7068const char *dvbapi_get_client_name(void)
7069{
7070 return last_client_name ? last_client_name : "";
7071}
7072
7073void check_add_emmpid(int32_t demux_index, uchar *filter, int32_t l, int32_t emmtype)
7074{
7075 if (l<0) return;
7076
7077 uint32_t typtext_idx = 0;
7078 int32_t ret = -1;
7079 const char *typtext[] = { "UNIQUE", "SHARED", "GLOBAL", "UNKNOWN" };
7080
7081 while(((emmtype >> typtext_idx) & 0x01) == 0 && typtext_idx < sizeof(typtext) / sizeof(const char *))
7082 {
7083 ++typtext_idx;
7084 }
7085
7086 //filter already in list?
7087 if(is_emmfilter_in_list(filter, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].PROVID, demux[demux_index].EMMpids[l].CAID))
7088 {
7089 cs_log_dbg(D_DVBAPI, "Demuxer %d duplicate emm filter type %s, emmpid: 0x%04X, emmcaid: %04X, emmprovid: %06X -> SKIPPED!", demux_index,
7090 typtext[typtext_idx], demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].CAID, demux[demux_index].EMMpids[l].PROVID);
7091 return;
7092 }
7093
7094 if(demux[demux_index].emm_filter < demux[demux_index].max_emm_filter) // can this filter be started?
7095 {
7096 // try to activate this emmfilter
7097 ret = dvbapi_set_filter(demux_index, selected_api, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].CAID,
7098 demux[demux_index].EMMpids[l].PROVID, filter, filter + 16, 0, demux[demux_index].pidindex, TYPE_EMM, 1);
7099 }
7100
7101 if(ret != -1) // -1 if maxfilter reached or filter start error!
7102 {
7103 if(demux[demux_index].emm_filter == -1) // -1: first run of emm filtering on this demuxer
7104 {
7105 demux[demux_index].emm_filter = 0;
7106 }
7107 demux[demux_index].emm_filter++; // increase total active filters
7108 cs_log_dump_dbg(D_DVBAPI, filter, 32, "Demuxer %d started emm filter type %s, pid: 0x%04X", demux_index, typtext[typtext_idx], demux[demux_index].EMMpids[l].PID);
7109 return;
7110 }
7111 else // not set successful, so add it to the list for try again later on!
7112 {
7113 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, 0, false);
7114 cs_log_dump_dbg(D_DVBAPI, filter, 32, "Demuxer %d added inactive emm filter type %s, pid: 0x%04X", demux_index, typtext[typtext_idx], demux[demux_index].EMMpids[l].PID);
7115 }
7116 return;
7117}
7118
7119void rotate_emmfilter(int32_t demux_id)
7120{
7121 // emm filter iteration
7122 if(!ll_emm_active_filter)
7123 { ll_emm_active_filter = ll_create("ll_emm_active_filter"); }
7124
7125 if(!ll_emm_inactive_filter)
7126 { ll_emm_inactive_filter = ll_create("ll_emm_inactive_filter"); }
7127
7128 if(!ll_emm_pending_filter)
7129 { ll_emm_pending_filter = ll_create("ll_emm_pending_filter"); }
7130
7131 uint32_t filter_count = ll_count(ll_emm_active_filter) + ll_count(ll_emm_inactive_filter);
7132
7133 if(demux[demux_id].max_emm_filter > 0
7134 && ll_count(ll_emm_inactive_filter) > 0
7135 && filter_count > demux[demux_id].max_emm_filter)
7136 {
7137
7138 int32_t filter_queue = ll_count(ll_emm_inactive_filter);
7139 int32_t stopped = 0, started = 0;
7140 struct timeb now;
7141 cs_ftime(&now);
7142
7143 struct s_emm_filter *filter_item;
7144 LL_ITER itr;
7145 itr = ll_iter_create(ll_emm_active_filter);
7146
7147 while((filter_item = ll_iter_next(&itr)) != NULL)
7148 {
7149 if(!ll_count(ll_emm_inactive_filter) || started == filter_queue)
7150 { break; }
7151 int64_t gone = comp_timeb(&now, &filter_item->time_started);
7152 if( gone > 45*1000)
7153 {
7154 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match_emmpid(filter_item->demux_id, filter_item->caid,
7155 filter_item->provid, 'p');
7156
7157 if(!forceentry || (forceentry && !forceentry->force))
7158 {
7159 // stop active filter and add to pending list
7160 dvbapi_stop_filternum(filter_item->demux_id, filter_item->num - 1);
7161 ll_iter_remove_data(&itr);
7162 add_emmfilter_to_list(filter_item->demux_id, filter_item->filter, filter_item->caid,
7163 filter_item->provid, filter_item->pid, -1, false);
7164 stopped++;
7165 }
7166 }
7167
7168 int32_t ret;
7169 if(stopped > started) // we have room for new filters, try to start an inactive emmfilter!
7170 {
7171 struct s_emm_filter *filter_item2;
7172 LL_ITER itr2 = ll_iter_create(ll_emm_inactive_filter);
7173
7174 while((filter_item2 = ll_iter_next(&itr2)))
7175 {
7176 ret = dvbapi_set_filter(filter_item2->demux_id, selected_api, filter_item2->pid, filter_item2->caid,
7177 filter_item2->provid, filter_item2->filter, filter_item2->filter + 16, 0,
7178 demux[filter_item2->demux_id].pidindex, TYPE_EMM, 1);
7179 if(ret != -1)
7180 {
7181 ll_iter_remove_data(&itr2);
7182 started++;
7183 break;
7184 }
7185 }
7186 }
7187 }
7188
7189 itr = ll_iter_create(ll_emm_pending_filter);
7190
7191 while((filter_item = ll_iter_next(&itr)) != NULL) // move pending filters to inactive
7192 {
7193 add_emmfilter_to_list(filter_item->demux_id, filter_item->filter, filter_item->caid, filter_item->provid, filter_item->pid, 0, false);
7194 ll_iter_remove_data(&itr);
7195 }
7196 }
7197}
7198
7199int32_t filtermatch(uchar *buffer, int32_t filter_num, int32_t demux_id, int32_t len)
7200{
7201 int32_t i, k, match;
7202 uint8_t flt, mask;
7203 match = 1;
7204 for(i = 0, k = 0; i < 16 && match; i++, k++)
7205 {
7206 mask = demux[demux_id].demux_fd[filter_num].mask[i];
7207 if(k == 1) //skip len bytes
7208 {
7209 k += 2;
7210 }
7211 if(!mask)
7212 {
7213 continue;
7214 }
7215 flt = (demux[demux_id].demux_fd[filter_num].filter[i]&mask);
7216 //cs_log_dbg(D_DVBAPI,"Demuxer %d filter%d[%d] = %02X, filter mask[%d] = %02X, flt&mask = %02X , buffer[%d] = %02X, buffer[%d] & mask = %02X", demux_id, filter_num+1, i,
7217 // demux[demux_id].demux_fd[filter_num].filter[i], i, mask, flt&mask, k, buffer[k], k, buffer[k] & mask);
7218 if(k <= len)
7219 {
7220 match = (flt == (buffer[k] & mask));
7221 }
7222 else
7223 {
7224 match = 0;
7225 }
7226 }
7227 return (match && i == 16); // 0 = delivered data does not match with filter, 1 = delivered data matches with filter
7228}
7229
7230/*
7231 * protocol structure
7232 */
7233
7234void module_dvbapi(struct s_module *ph)
7235{
7236 ph->desc = "dvbapi";
7237 ph->type = MOD_CONN_SERIAL;
7238 ph->listenertype = LIS_DVBAPI;
7239#if defined(WITH_AZBOX)
7240 ph->s_handler = azbox_handler;
7241 ph->send_dcw = azbox_send_dcw;
7242#elif defined(WITH_MCA)
7243 ph->s_handler = mca_handler;
7244 ph->send_dcw = mca_send_dcw;
7245 selected_box = selected_api = 0; // HACK: This fixes incorrect warning about out of bounds array access in functionas that are not even called when WITH_MCA is defined
7246#else
7247 ph->s_handler = dvbapi_handler;
7248 ph->send_dcw = dvbapi_send_dcw;
7249#endif
7250}
7251#endif // HAVE_DVBAPI
Note: See TracBrowser for help on using the repository browser.