1 #define MODULE_LOG_PREFIX "dvbapi"
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"
29 extern int32_t exit_oscam
;
31 #if defined (__CYGWIN__)
37 #define DN_MULTISHOT 0
40 const char *streamtxt_00_to_1B
[] = {
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
71 const 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
82 const char *get_streamtxt(uint8_t id
)
86 return streamtxt_00_to_1B
[id
];
90 return "Videostream (H.265 Ultra HD video)";
94 return "Videostream (Chinese Video Standard)";
96 else if(id
>= 0x80 && id
<= 0x87)
98 return streamtxt_80_to_87
[id
- 0x80];
102 return "Datastream (Blu-ray subtitling)";
106 return "Datastream (DSM CC)";
110 return "Datastream (DigiCipher II text)";
114 return "Datastream (DSM CC)";
118 return "Videostream (BBC Dirac Ultra HD video)";
122 return "Videostream (WMV9 lower bit-rate)";
131 void flush_read_fd(int32_t demux_index
, int32_t num
, int fd
)
133 if(!cfg
.dvbapi_listenport
&& cfg
.dvbapi_boxtype
!= BOXTYPE_PC_NODMX
)
135 cs_log_dbg(D_DVBAPI
,"Demuxer %d flushing stale input data of filter %d (fd:%d)", demux_index
, num
+ 1, fd
);
143 while(select(fd
+1,&rd
,NULL
,NULL
,&t
) > 0)
145 if (read(fd
,buff
,100)){;}
150 static int dvbapi_ioctl(int fd
, uint32_t request
, ...)
154 va_start(args
, request
);
155 if (!(cfg
.dvbapi_boxtype
== BOXTYPE_SAMYGO
))
157 void *param
= va_arg(args
, void *);
158 ret
= ioctl(fd
, request
, param
);
166 struct dmx_sct_filter_params
*sFP
= va_arg(args
, struct dmx_sct_filter_params
*);
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);
173 memmove(&sFP
->filter
.mask
[3], &sFP
->filter
.mask
[1], 13);
174 memset(&sFP
->filter
.mask
[1], 0, 2);
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);
183 case DMX_SET_FILTER1
:
185 cs_log("error: samygo does not support DMX_SET_FILTER1");
191 ret
= send(fd
, &request
, sizeof(request
), 0);
197 ca_pid_t
*ca_pid2
= va_arg(args
, ca_pid_t
*);
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
));
204 // sending data to UDP
205 ret
= send(fd
, &packet
[0], sizeof(packet
), 0);
210 ca_descr_t
*ca_descr
= va_arg(args
, ca_descr_t
*);
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
));
217 // sending data to UDP
218 ret
= send(fd
, &packet
[0], sizeof(packet
), 0);
221 case CA_SET_DESCR_MODE
:
223 cs_log("error: samygo does not support CA_SET_DESCR_MODE");
228 if (ret
> 0) // send() may return larger than 1
231 #if defined(__powerpc__)
232 // Old dm500 boxes (ppc old) are using broken kernel, se we need some fixups
241 // FIXME: Workaround for su980 bug
242 // See: http://www.streamboard.tv/wbb2/thread.php?postid=533940
243 if(boxtype_is("su980"))
253 #if defined(CARDREADER_STAPI) || defined(CARDREADER_STAPI5)
254 //fix from stapi5 patch
255 int32_t pausecam
= 0, disable_pmt_files
= 0, pmt_stopmarking
= 1;
257 int32_t pausecam
= 0, disable_pmt_files
= 0, pmt_stopmarking
= 0;
260 DEMUXTYPE demux
[MAX_DEMUX
];
261 struct s_dvbapi_priority
*dvbapi_priority
;
262 struct s_client
*dvbapi_client
;
264 const char *boxdesc
[] = { "none", "dreambox", "duckbox", "ufs910", "dbox2", "ipbox", "ipbox-pmt", "dm7000", "qboxhd", "coolstream", "neumo", "pc", "pc-nodmx", "samygo" };
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
272 static const struct box_devices devices
[BOX_COUNT
] =
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
},
280 /* sh4 (stapi5)*/ { "/dev/stapi/", "stpti5_ioctl", "stpti5_ioctl", "/tmp/camd.socket", STAPI
},
282 /* sh4 (stapi)*/ { "/dev/stapi/", "stpti4_ioctl", "stpti4_ioctl", "/tmp/camd.socket", STAPI
},
284 /* coolstream*/ { "/dev/cnxt/", "null", "null", "/tmp/camd.socket", COOLAPI
},
287 static int32_t selected_box
= -1;
288 static int32_t selected_api
= -1;
289 static int32_t maxfilter
= MAX_FILTER
;
290 static int32_t dir_fd
= -1;
291 static uint16_t last_client_proto_version
= 0;
292 static char* last_client_name
= NULL
;
294 static int32_t ca_fd
[MAX_DEMUX
]; // holds fd handle of each ca device 0 = not in use
295 static LLIST
* ll_activestreampids
; // list of all enabled streampids on ca devices
297 static int32_t unassoc_fd
[MAX_DEMUX
];
299 bool is_dvbapi_usr(char *usr
) {
300 return streq(cfg
.dvbapi_usr
, usr
);
311 struct timeb time_started
;
314 static LLIST
*ll_emm_active_filter
;
315 static LLIST
*ll_emm_inactive_filter
;
316 static LLIST
*ll_emm_pending_filter
;
318 int32_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
)
320 if(!ll_emm_active_filter
)
321 { ll_emm_active_filter
= ll_create("ll_emm_active_filter"); }
323 if(!ll_emm_inactive_filter
)
324 { ll_emm_inactive_filter
= ll_create("ll_emm_inactive_filter"); }
326 if(!ll_emm_pending_filter
)
327 { ll_emm_pending_filter
= ll_create("ll_emm_pending_filter"); }
329 struct s_emm_filter
*filter_item
;
330 if(!cs_malloc(&filter_item
, sizeof(struct s_emm_filter
)))
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
;
341 cs_ftime(&filter_item
->time_started
);
345 memset(&filter_item
->time_started
, 0, sizeof(filter_item
->time_started
));
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
);
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
);
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
);
369 int32_t is_emmfilter_in_list_internal(LLIST
*ll
, uchar
*filter
, uint16_t emmpid
, uint32_t provid
, uint16_t caid
)
371 struct s_emm_filter
*filter_item
;
375 itr
= ll_iter_create(ll
);
376 while((filter_item
= ll_iter_next(&itr
)) != NULL
)
378 if(!memcmp(filter_item
->filter
, filter
, 32) && (filter_item
->pid
== emmpid
) && (filter_item
->provid
== provid
) && (filter_item
->caid
== caid
))
385 int32_t is_emmfilter_in_list(uchar
*filter
, uint16_t emmpid
, uint32_t provid
, uint16_t caid
)
387 if(!ll_emm_active_filter
)
388 { ll_emm_active_filter
= ll_create("ll_emm_active_filter"); }
390 if(!ll_emm_inactive_filter
)
391 { ll_emm_inactive_filter
= ll_create("ll_emm_inactive_filter"); }
393 if(!ll_emm_pending_filter
)
394 { ll_emm_pending_filter
= ll_create("ll_emm_pending_filter"); }
396 if(is_emmfilter_in_list_internal(ll_emm_active_filter
, filter
, emmpid
, provid
, caid
))
398 if(is_emmfilter_in_list_internal(ll_emm_inactive_filter
, filter
, emmpid
, provid
, caid
))
400 if(is_emmfilter_in_list_internal(ll_emm_pending_filter
, filter
, emmpid
, provid
, caid
))
406 struct s_emm_filter
*get_emmfilter_by_filternum_internal(LLIST
*ll
, int32_t demux_id
, uint32_t num
)
408 struct s_emm_filter
*filter
;
412 itr
= ll_iter_create(ll
);
413 while((filter
= ll_iter_next(&itr
)))
415 if(filter
->demux_id
== demux_id
&& filter
->num
== num
)
422 struct s_emm_filter
*get_emmfilter_by_filternum(int32_t demux_id
, uint32_t num
)
424 if(!ll_emm_active_filter
)
425 { ll_emm_active_filter
= ll_create("ll_emm_active_filter"); }
427 if(!ll_emm_inactive_filter
)
428 { ll_emm_inactive_filter
= ll_create("ll_emm_inactive_filter"); }
430 if(!ll_emm_pending_filter
)
431 { ll_emm_pending_filter
= ll_create("ll_emm_pending_filter"); }
433 struct s_emm_filter
*emm_filter
= NULL
;
434 emm_filter
= get_emmfilter_by_filternum_internal(ll_emm_active_filter
, demux_id
, num
);
436 { return emm_filter
; }
437 emm_filter
= get_emmfilter_by_filternum_internal(ll_emm_inactive_filter
, demux_id
, num
);
439 { return emm_filter
; }
440 emm_filter
= get_emmfilter_by_filternum_internal(ll_emm_pending_filter
, demux_id
, num
);
442 { return emm_filter
; }
447 int8_t remove_emmfilter_from_list_internal(LLIST
*ll
, int32_t demux_id
, uint16_t caid
, uint32_t provid
, uint16_t pid
, uint32_t num
)
449 struct s_emm_filter
*filter
;
453 itr
= ll_iter_create(ll
);
454 while((filter
= ll_iter_next(&itr
)))
456 if(filter
->demux_id
== demux_id
&& filter
->caid
== caid
&& filter
->provid
== provid
&& filter
->pid
== pid
&& filter
->num
== num
)
458 ll_iter_remove_data(&itr
);
466 void remove_emmfilter_from_list(int32_t demux_id
, uint16_t caid
, uint32_t provid
, uint16_t pid
, uint32_t num
)
468 if(ll_emm_active_filter
&& remove_emmfilter_from_list_internal(ll_emm_active_filter
, demux_id
, caid
, provid
, pid
, num
))
470 if(ll_emm_inactive_filter
&& remove_emmfilter_from_list_internal(ll_emm_inactive_filter
, demux_id
, caid
, provid
, pid
, num
))
472 if(ll_emm_pending_filter
&& remove_emmfilter_from_list_internal(ll_emm_pending_filter
, demux_id
, caid
, provid
, pid
, num
))
476 void dvbapi_net_add_str(unsigned char *packet
, int *size
, const char *str
)
478 unsigned char *str_len
= &packet
[*size
]; //string length
481 *str_len
= snprintf((char *) &packet
[*size
], DVBAPI_MAX_PACKET_SIZE
- *size
, "%s", str
);
485 int32_t dvbapi_net_send(uint32_t request
, int32_t socket_fd
, uint32_t msgid
, int32_t demux_index
, uint32_t filter_number
, unsigned char *data
, struct s_client
*client
, ECM_REQUEST
*er
, uint16_t client_proto_version
)
487 unsigned char packet
[DVBAPI_MAX_PACKET_SIZE
]; //maximum possible packet size
495 // preparing packet - header
496 // in old protocol client expect this first byte as adapter index, changed in the new protocol
497 // to be always after request type (opcode)
498 if (client_proto_version
<= 0)
499 packet
[size
++] = demux
[demux_index
].adapter_index
; //adapter index - 1 byte
500 else if (client_proto_version
>= 3) {
501 packet
[size
++] = 0xa5; //message start
503 memcpy(&packet
[size
], &u32
, 4);
509 if (client_proto_version
>= 1)
511 memcpy(&packet
[size
], &u32
, 4);
514 // preparing packet - adapter index for proto >= 1
515 if ((request
!= DVBAPI_SERVER_INFO
) && client_proto_version
>= 1)
516 packet
[size
++] = demux
[demux_index
].adapter_index
; //adapter index - 1 byte
521 case DVBAPI_SERVER_INFO
:
523 int16_t proto_version
= htons(DVBAPI_PROTOCOL_VERSION
); //our protocol version
524 char capabilities
[128] = "\x00"; // two zero characters
525 memcpy(&packet
[size
], &proto_version
, 2);
528 unsigned char *info_len
= &packet
[size
]; //info string length
531 if (cfg
.dvbapi_extended_cw_api
== 1)
532 strcat(capabilities
, ",e1km"); //extended cw, mode follows key
533 if (cfg
.dvbapi_extended_cw_api
== 2)
534 strcat(capabilities
, ",e2");
536 *info_len
= snprintf((char *) &packet
[size
], sizeof(packet
) - size
, "OSCam v%s, build r%s (%s); %s", CS_VERSION
, CS_SVN_VERSION
, CS_TARGET
, capabilities
+ 1);
540 case DVBAPI_ECM_INFO
:
542 if (er
->rc
>= E_NOTFOUND
)
547 uint16_t sid
= htons(er
->srvid
); //service ID (program number)
548 memcpy(&packet
[size
], &sid
, 2);
551 uint16_t caid
= htons(er
->caid
); //CAID
552 memcpy(&packet
[size
], &caid
, 2);
555 uint16_t pid
= htons(er
->pid
); //PID
556 memcpy(&packet
[size
], &pid
, 2);
559 uint32_t prid
= htonl(er
->prid
); //Provider ID
560 memcpy(&packet
[size
], &prid
, 4);
563 uint32_t ecmtime
= htonl(client
->cwlastresptime
); //ECM time
564 memcpy(&packet
[size
], &ecmtime
, 4);
567 dvbapi_net_add_str(packet
, &size
, get_cardsystem_desc_by_caid(er
->caid
)); //cardsystem name
572 if (er
->selected_reader
)
574 dvbapi_net_add_str(packet
, &size
, er
->selected_reader
->label
); //reader
575 if (is_network_reader(er
->selected_reader
))
576 dvbapi_net_add_str(packet
, &size
, er
->selected_reader
->device
); //from
578 dvbapi_net_add_str(packet
, &size
, "local"); //from
579 dvbapi_net_add_str(packet
, &size
, reader_get_type_desc(er
->selected_reader
, 1)); //protocol
580 hops
= er
->selected_reader
->currenthops
;
585 dvbapi_net_add_str(packet
, &size
, "Cache"); //reader
586 dvbapi_net_add_str(packet
, &size
, "cache1"); //from
587 dvbapi_net_add_str(packet
, &size
, "none"); //protocol
591 dvbapi_net_add_str(packet
, &size
, "Cache"); //reader
592 dvbapi_net_add_str(packet
, &size
, "cache2"); //from
593 dvbapi_net_add_str(packet
, &size
, "none"); //protocol
597 dvbapi_net_add_str(packet
, &size
, "Cache"); //reader
598 dvbapi_net_add_str(packet
, &size
, "cache3"); //from
599 dvbapi_net_add_str(packet
, &size
, "none"); //protocol
603 packet
[size
++] = hops
; //hops
607 case DVBAPI_CA_SET_PID
:
609 int sct_capid_size
= sizeof(ca_pid_t
);
611 if (client_proto_version
>= 1)
613 ca_pid_t
*capid
= (ca_pid_t
*) data
;
614 capid
->pid
= htonl(capid
->pid
);
615 capid
->index
= htonl(capid
->index
);
617 memcpy(&packet
[size
], data
, sct_capid_size
);
619 size
+= sct_capid_size
;
622 case DVBAPI_CA_SET_DESCR
:
624 int sct_cadescr_size
= sizeof(ca_descr_t
);
626 if (client_proto_version
>= 1)
628 ca_descr_t
*cadesc
= (ca_descr_t
*) data
;
629 cadesc
->index
= htonl(cadesc
->index
);
630 cadesc
->parity
= htonl(cadesc
->parity
);
632 memcpy(&packet
[size
], data
, sct_cadescr_size
);
634 size
+= sct_cadescr_size
;
637 case DVBAPI_CA_SET_DESCR_MODE
:
639 int sct_cadescr_mode_size
= sizeof(ca_descr_mode_t
);
641 if (client_proto_version
>= 1)
643 ca_descr_mode_t
*cadesc_mode
= (ca_descr_mode_t
*) data
;
644 cadesc_mode
->index
= htonl(cadesc_mode
->index
);
645 cadesc_mode
->algo
= htonl(cadesc_mode
->algo
);
646 cadesc_mode
->cipher_mode
= htonl(cadesc_mode
->cipher_mode
);
648 memcpy(&packet
[size
], data
, sct_cadescr_mode_size
);
650 size
+= sct_cadescr_mode_size
;
653 case DVBAPI_DMX_SET_FILTER
:
654 case DVBAPI_DMX_STOP
:
656 int32_t sct_filter_size
= sizeof(struct dmx_sct_filter_params
);
657 packet
[size
++] = demux_index
; //demux index - 1 byte
658 packet
[size
++] = filter_number
; //filter number - 1 byte
660 if (data
) // filter data when starting
662 if (client_proto_version
>= 1)
664 struct dmx_sct_filter_params
*fp
= (struct dmx_sct_filter_params
*) data
;
666 // adding all dmx_sct_filter_params structure fields
667 // one by one to avoid padding problems
668 uint16_t pid
= htons(fp
->pid
);
669 memcpy(&packet
[size
], &pid
, 2);
672 memcpy(&packet
[size
], fp
->filter
.filter
, 16);
674 memcpy(&packet
[size
], fp
->filter
.mask
, 16);
676 memcpy(&packet
[size
], fp
->filter
.mode
, 16);
679 uint32_t timeout
= htonl(fp
->timeout
);
680 memcpy(&packet
[size
], &timeout
, 4);
683 uint32_t flags
= htonl(fp
->flags
);
684 memcpy(&packet
[size
], &flags
, 4);
689 memcpy(&packet
[size
], data
, sct_filter_size
); //dmx_sct_filter_params struct
690 size
+= sct_filter_size
;
693 else // pid when stopping
695 if (client_proto_version
>= 1)
697 uint16_t pid
= htons(demux
[demux_index
].demux_fd
[filter_number
].pid
);
698 memcpy(&packet
[size
], &pid
, 2);
703 uint16_t pid
= demux
[demux_index
].demux_fd
[filter_number
].pid
;
704 packet
[size
++] = pid
>> 8;
705 packet
[size
++] = pid
& 0xff;
710 default: //unknown request
712 cs_log("ERROR: dvbapi_net_send: invalid request");
718 cs_log_dump_dbg(D_DVBAPI
, packet
, size
, "Sending packet to dvbapi client (fd=%d):", socket_fd
);
719 send(socket_fd
, &packet
, size
, MSG_DONTWAIT
);
721 // always returning success as the client could close socket
725 int32_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
,
726 int8_t add_to_emm_list
)
728 int32_t ret
= -1, n
= -1, i
, filterfd
= -1;
730 for(i
= 0; i
< maxfilter
&& demux
[demux_id
].demux_fd
[i
].fd
> 0; i
++) { ; }
734 cs_log_dbg(D_DVBAPI
, "no free filter");
743 openxcas_set_caid(demux
[demux_id
].ECMpids
[pidindex
].CAID
);
744 openxcas_set_ecm_pid(pid
);
746 demux
[demux_id
].demux_fd
[n
].fd
= DUMMY_FD
;
747 demux
[demux_id
].demux_fd
[n
].pidindex
= pidindex
;
748 demux
[demux_id
].demux_fd
[n
].pid
= pid
;
749 demux
[demux_id
].demux_fd
[n
].caid
= caid
;
750 demux
[demux_id
].demux_fd
[n
].provid
= provid
;
751 demux
[demux_id
].demux_fd
[n
].type
= type
;
752 memcpy(demux
[demux_id
].demux_fd
[n
].filter
, filt
, 16); // copy filter to check later on if receiver delivered accordingly
753 memcpy(demux
[demux_id
].demux_fd
[n
].mask
, mask
, 16); // copy mask to check later on if receiver delivered accordingly
760 if (cfg
.dvbapi_listenport
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)
761 ret
= filterfd
= DUMMY_FD
;
763 ret
= filterfd
= dvbapi_open_device(0, demux
[demux_id
].demux_index
, demux
[demux_id
].adapter_index
);
764 if(ret
< 0) { return ret
; } // return if device cant be opened!
765 struct dmx_sct_filter_params sFP2
;
767 memset(&sFP2
, 0, sizeof(sFP2
));
770 sFP2
.timeout
= timeout
;
771 sFP2
.flags
= DMX_IMMEDIATE_START
;
772 if(cfg
.dvbapi_boxtype
== BOXTYPE_NEUMO
)
774 //DeepThought: on dgs/cubestation and neumo images, perhaps others
775 //the following code is needed to descramble
776 sFP2
.filter
.filter
[0] = filt
[0];
777 sFP2
.filter
.mask
[0] = mask
[0];
778 sFP2
.filter
.filter
[1] = 0;
779 sFP2
.filter
.mask
[1] = 0;
780 sFP2
.filter
.filter
[2] = 0;
781 sFP2
.filter
.mask
[2] = 0;
782 memcpy(sFP2
.filter
.filter
+ 3, filt
+ 1, 16 - 3);
783 memcpy(sFP2
.filter
.mask
+ 3, mask
+ 1, 16 - 3);
784 //DeepThought: in the drivers of the dgs/cubestation and neumo images,
785 //dvbapi 1 and 3 are somehow mixed. In the kernel drivers, the DMX_SET_FILTER
786 //ioctl expects to receive a dmx_sct_filter_params structure (DVBAPI 3) but
787 //due to a bug its sets the "positive mask" wrongly (they should be all 0).
788 //On the other hand, the DMX_SET_FILTER1 ioctl also uses the dmx_sct_filter_params
789 //structure, which is incorrect (it should be dmxSctFilterParams).
790 //The only way to get it right is to call DMX_SET_FILTER1 with the argument
791 //expected by DMX_SET_FILTER. Otherwise, the timeout parameter is not passed correctly.
792 ret
= dvbapi_ioctl(filterfd
, DMX_SET_FILTER1
, &sFP2
);
796 memcpy(sFP2
.filter
.filter
, filt
, 16);
797 memcpy(sFP2
.filter
.mask
, mask
, 16);
798 if (cfg
.dvbapi_listenport
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)
799 ret
= dvbapi_net_send(DVBAPI_DMX_SET_FILTER
, demux
[demux_id
].socket_fd
, 0, demux_id
, n
, (unsigned char *) &sFP2
, NULL
, NULL
, demux
[demux_id
].client_proto_version
);
801 ret
= dvbapi_ioctl(filterfd
, DMX_SET_FILTER
, &sFP2
);
806 ret
= filterfd
= dvbapi_open_device(0, demux
[demux_id
].demux_index
, demux
[demux_id
].adapter_index
);
807 if(ret
< 0) { return ret
; } // return if device cant be opened!
808 struct dmxSctFilterParams sFP1
;
810 memset(&sFP1
, 0, sizeof(sFP1
));
813 sFP1
.timeout
= timeout
;
814 sFP1
.flags
= DMX_IMMEDIATE_START
;
815 memcpy(sFP1
.filter
.filter
, filt
, 16);
816 memcpy(sFP1
.filter
.mask
, mask
, 16);
817 ret
= dvbapi_ioctl(filterfd
, DMX_SET_FILTER1
, &sFP1
);
820 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
822 ret
= filterfd
= stapi_set_filter(demux_id
, pid
, filt
, mask
, n
, demux
[demux_id
].pmt_file
);
825 ret
= -1; // error setting filter!
829 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
831 ret
= filterfd
= coolapi_open_device(demux
[demux_id
].demux_index
, demux_id
);
834 ret
= coolapi_set_filter(filterfd
, n
, pid
, filt
, mask
, type
);
845 if(ret
!= -1) // filter set successful
847 // only register if filter was set successful
848 demux
[demux_id
].demux_fd
[n
].fd
= filterfd
;
849 demux
[demux_id
].demux_fd
[n
].pidindex
= pidindex
;
850 demux
[demux_id
].demux_fd
[n
].pid
= pid
;
851 demux
[demux_id
].demux_fd
[n
].caid
= caid
;
852 demux
[demux_id
].demux_fd
[n
].provid
= provid
;
853 demux
[demux_id
].demux_fd
[n
].type
= type
;
854 memcpy(demux
[demux_id
].demux_fd
[n
].filter
, filt
, 16); // copy filter to check later on if receiver delivered accordingly
855 memcpy(demux
[demux_id
].demux_fd
[n
].mask
, mask
, 16); // copy mask to check later on if receiver delivered accordingly
856 cs_log_dbg(D_DVBAPI
, "Demuxer %d Filter %d started successfully (caid %04X provid %06X pid %04X)", demux_id
, n
+ 1, caid
, provid
, pid
);
857 if(type
== TYPE_EMM
&& add_to_emm_list
){
858 add_emmfilter_to_list(demux_id
, filt
, caid
, provid
, pid
, n
+ 1, true);
863 cs_log("ERROR: Could not start demux filter (api: %d errno=%d %s)", selected_api
, errno
, strerror(errno
));
869 static int32_t dvbapi_detect_api(void)
871 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
872 selected_api
= COOLAPI
;
873 selected_box
= BOX_INDEX_COOLSTREAM
;
874 disable_pmt_files
= 1;
875 cfg
.dvbapi_listenport
= 0;
876 cs_log("Detected Coolstream API");
879 if (cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC
) {
880 selected_api
= DVBAPI_3
;
881 selected_box
= BOX_INDEX_DREAMBOX_DVBAPI3
;
882 if (cfg
.dvbapi_listenport
)
884 cs_log("Using TCP listen socket, API forced to DVBAPIv3 (%d), userconfig boxtype: %d", selected_api
, cfg
.dvbapi_boxtype
);
888 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
);
892 else if(cfg
.dvbapi_boxtype
== BOXTYPE_SAMYGO
)
894 selected_api
= DVBAPI_3
;
895 selected_box
= BOX_INDEX_QBOXHD
;
896 cfg
.dvbapi_listenport
= 0;
897 disable_pmt_files
= 1;
898 cs_log("Using SamyGO dvbapi v0.1");
903 cfg
.dvbapi_listenport
= 0;
906 int32_t i
= 0, n
= 0, devnum
= -1, dmx_fd
= 0, filtercount
= 0;
907 char device_path
[128], device_path2
[128];
908 static LLIST
*ll_max_fd
;
909 ll_max_fd
= ll_create("ll_max_fd");
917 struct s_open_fd
*open_fd
;
919 while (i
< BOX_COUNT
)
923 snprintf(device_path2
, sizeof(device_path2
), devices
[i
].demux_device
, 0);
924 snprintf(device_path
, sizeof(device_path
), devices
[i
].path
, n
);
925 strncat(device_path
, device_path2
, sizeof(device_path
) - strlen(device_path
) - 1);
927 while((dmx_fd
= open(device_path
, O_RDWR
| O_NONBLOCK
)) > 0 && filtercount
< MAX_FILTER
)
930 if(!cs_malloc(&open_fd
, sizeof(struct s_open_fd
)))
935 open_fd
->fd
= dmx_fd
;
936 ll_append(ll_max_fd
, open_fd
);
941 itr
= ll_iter_create(ll_max_fd
);
942 while((open_fd
= ll_iter_next(&itr
)))
944 dmx_fd
= open_fd
->fd
;
949 while(close(dmx_fd
)<0);
950 ll_iter_remove_data(&itr
);
953 selected_api
= devices
[devnum
].api
;
954 selected_box
= devnum
;
955 if(cfg
.dvbapi_boxtype
== BOXTYPE_NEUMO
)
957 selected_api
= DVBAPI_3
; //DeepThought
959 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
960 if(selected_api
== STAPI
&& stapi_open() == 0)
962 cs_log("ERROR: stapi: setting up stapi failed.");
966 maxfilter
= filtercount
;
967 cs_log("Detected %s Api: %d, userconfig boxtype: %d maximum amount of possible filters is %d (oscam limit is %d)",
968 device_path
, selected_api
, cfg
.dvbapi_boxtype
, filtercount
, MAX_FILTER
);
971 /* try at least 8 adapters */
972 if ((strchr(devices
[i
].path
, '%') != NULL
) && (n
< 8)) n
++; else { n
= 0; i
++; }
973 }while(n
!= 0); // n is set to 0 again if 8 adapters are tried!
975 if(devnum
!= -1) break; // check if box detected
978 ll_destroy(&ll_max_fd
);
980 if(devnum
== -1) { return 0; }
986 static int32_t dvbapi_read_device(int32_t dmx_fd
, unsigned char *buf
, uint32_t length
)
990 struct pollfd pfd
[1];
993 pfd
[0].events
= (POLLIN
| POLLPRI
);
995 while (count
< length
)
997 if (poll(pfd
,1,0)) // fd ready for reading?
999 if (pfd
[0].revents
& (POLLIN
| POLLPRI
)) // is there data to read?
1001 readed
= read(dmx_fd
, &buf
[count
], length
-count
);
1002 if(readed
< 0) // error occured while reading
1004 if(errno
== EINTR
|| errno
== EAGAIN
) { continue; } // try again in case of interrupt
1005 cs_log("ERROR: Read error on fd %d (errno=%d %s)", dmx_fd
, errno
, strerror(errno
));
1006 return (errno
== EOVERFLOW
? 0 : -1);
1008 if(readed
> 0) // succesfull read
1012 if(readed
== 0 && count
> 0) // nothing to read left
1017 else return -1; // other events than pollin/pri means bad news -> abort!
1021 cs_log_dump_dbg(D_TRACE
, buf
, count
, "Received:");
1025 int32_t dvbapi_open_device(int32_t type
, int32_t num
, int32_t adapter
)
1027 int32_t dmx_fd
, ret
;
1028 int32_t ca_offset
= 0;
1029 char device_path
[128], device_path2
[128];
1031 if(cfg
.dvbapi_listenport
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)
1036 snprintf(device_path2
, sizeof(device_path2
), devices
[selected_box
].demux_device
, num
);
1037 snprintf(device_path
, sizeof(device_path
), devices
[selected_box
].path
, adapter
);
1039 strncat(device_path
, device_path2
, sizeof(device_path
) - strlen(device_path
) - 1);
1043 if(cfg
.dvbapi_boxtype
== BOXTYPE_DUCKBOX
|| cfg
.dvbapi_boxtype
== BOXTYPE_DBOX2
|| cfg
.dvbapi_boxtype
== BOXTYPE_UFS910
)
1046 if(cfg
.dvbapi_boxtype
== BOXTYPE_QBOXHD
)
1049 if(cfg
.dvbapi_boxtype
== BOXTYPE_PC
)
1052 if(cfg
.dvbapi_boxtype
== BOXTYPE_SAMYGO
)
1055 snprintf(device_path2
, sizeof(device_path2
), devices
[selected_box
].ca_device
, num
+ ca_offset
);
1056 snprintf(device_path
, sizeof(device_path
), devices
[selected_box
].path
, adapter
);
1058 strncat(device_path
, device_path2
, sizeof(device_path
) - strlen(device_path
) - 1);
1061 if (cfg
.dvbapi_boxtype
== BOXTYPE_SAMYGO
) {
1065 struct sockaddr_un saddr
;
1066 memset(&saddr
, 0, sizeof(saddr
));
1067 saddr
.sun_family
= AF_UNIX
;
1068 strncpy(saddr
.sun_path
, device_path
, sizeof(saddr
.sun_path
) - 1);
1069 dmx_fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
1070 ret
= connect(dmx_fd
, (struct sockaddr
*)&saddr
, sizeof(saddr
));
1076 int32_t udp_port
= 9000;
1077 struct sockaddr_in saddr
;
1078 memset(&saddr
, 0, sizeof(saddr
));
1079 saddr
.sin_family
= AF_INET
;
1080 saddr
.sin_port
= htons(udp_port
+ adapter
);
1081 saddr
.sin_addr
.s_addr
= inet_addr("127.0.0.1");
1082 dmx_fd
= socket(PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1083 set_nonblock(dmx_fd
, true);
1084 ret
= connect(dmx_fd
, (struct sockaddr
*) &saddr
, sizeof(saddr
));
1087 cs_log_dbg(D_DVBAPI
, "NET DEVICE open (port = %d) fd %d", udp_port
+ adapter
, dmx_fd
);
1094 dmx_fd
= ret
= open(device_path
, O_RDWR
| O_NONBLOCK
);
1099 cs_log("ERROR: Can't open device %s (errno=%d %s)", device_path
, errno
, strerror(errno
));
1103 cs_log_dbg(D_DVBAPI
, "Open device %s (fd %d)", device_path
, dmx_fd
);
1108 uint16_t tunemm_caid_map(uint8_t direct
, uint16_t caid
, uint16_t srvid
)
1111 struct s_client
*cl
= cur_client();
1112 TUNTAB
*ttab
= &cl
->ttab
;
1119 for(i
= 0; i
< ttab
->ttnum
; i
++)
1121 if(caid
== ttab
->ttdata
[i
].bt_caidto
1122 && (srvid
== ttab
->ttdata
[i
].bt_srvid
|| ttab
->ttdata
[i
].bt_srvid
== 0xFFFF || !ttab
->ttdata
[i
].bt_srvid
))
1123 { return ttab
->ttdata
[i
].bt_caidfrom
; }
1128 for(i
= 0; i
< ttab
->ttnum
; i
++)
1130 if(caid
== ttab
->ttdata
[i
].bt_caidfrom
1131 && (srvid
== ttab
->ttdata
[i
].bt_srvid
|| ttab
->ttdata
[i
].bt_srvid
== 0xFFFF || !ttab
->ttdata
[i
].bt_srvid
))
1132 { return ttab
->ttdata
[i
].bt_caidto
; }
1138 int32_t dvbapi_stop_filter(int32_t demux_index
, int32_t type
, uint32_t msgid
)
1140 #if defined(WITH_COOLAPI) || defined(WITH_COOLAPI2)
1141 // We prevented PAT and PMT from starting, so lets don't close them either.
1142 if (type
!= TYPE_ECM
&& type
!= TYPE_EMM
&& type
!= TYPE_SDT
) {
1147 int32_t g
, error
= 0;
1149 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
1151 if(demux
[demux_index
].demux_fd
[g
].type
== type
)
1153 if(dvbapi_stop_filternum(demux_index
, g
, msgid
) == -1)
1159 return !error
; // on error return 0, all ok 1
1162 int32_t dvbapi_stop_filternum(int32_t demux_index
, int32_t num
, uint32_t msgid
)
1164 int32_t retfilter
= -1, retfd
= -1, fd
= demux
[demux_index
].demux_fd
[num
].fd
, try = 0;
1167 demux
[demux_index
].demux_fd
[num
].type
= 0;
1168 demux
[demux_index
].demux_fd
[num
].fd
= 0;
1169 return 1; // all ok!
1182 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,
1183 fd
, selected_api
, demux
[demux_index
].demux_fd
[num
].caid
, demux
[demux_index
].demux_fd
[num
].provid
,
1184 (demux
[demux_index
].demux_fd
[num
].type
== TYPE_ECM
? "ecm" : "emm"), demux
[demux_index
].demux_fd
[num
].pid
);
1186 switch(selected_api
)
1189 if (cfg
.dvbapi_listenport
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)
1190 retfilter
= dvbapi_net_send(DVBAPI_DMX_STOP
, demux
[demux_index
].socket_fd
, msgid
, demux_index
, num
, NULL
, NULL
, NULL
, demux
[demux_index
].client_proto_version
);
1192 retfilter
= dvbapi_ioctl(fd
, DMX_STOP
, NULL
);
1196 retfilter
= dvbapi_ioctl(fd
, DMX_STOP
, NULL
);
1199 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
1201 retfilter
= stapi_remove_filter(demux_index
, num
, demux
[demux_index
].pmt_file
);
1202 if(retfilter
!= 1) // stapi returns 0 for error, 1 for all ok
1208 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
1210 retfilter
= coolapi_remove_filter(fd
, num
);
1213 retfd
= coolapi_close_device(fd
);
1220 if(errno
== 9) {retfilter
= 0;} // no error on bad file descriptor
1221 } while (retfilter
< 0 && try < 10);
1223 #if !defined WITH_COOLAPI && !defined WITH_COOLAPI2 // no fd close for coolapi and stapi, all others do close fd!
1233 if (!cfg
.dvbapi_listenport
&& cfg
.dvbapi_boxtype
!= BOXTYPE_PC_NODMX
&& errno
!= 9) //on bad filterfd dont try to close!
1235 if(selected_api
== STAPI
)
1237 retfd
= 0; // stapi closes its own filter fd!
1241 flush_read_fd(demux_index
, num
, fd
); // flush filter input buffer in attempt to avoid overflow receivers internal buffer
1243 if(errno
== 9) { retfd
= 0; } // no error on bad file descriptor
1249 } while (retfd
< 0 && try < 10);
1254 return 1; // filter was already killed!
1257 if(retfilter
< 0) // error on remove filter
1259 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
));
1263 if(retfd
< 0) // error on close filter fd
1265 cs_log("ERROR: Demuxer %d could not close fd of Filter %d (fd=%d api:%d errno=%d %s)", demux_index
, num
+ 1, fd
,
1266 selected_api
, errno
, strerror(errno
));
1270 // code below runs only if nothing has gone wrong
1272 if(demux
[demux_index
].demux_fd
[num
].type
== TYPE_ECM
) //ecm filter stopped: reset index!
1274 int32_t oldpid
= demux
[demux_index
].demux_fd
[num
].pidindex
;
1275 int32_t curpid
= demux
[demux_index
].pidindex
;
1277 // workaround: below dont run on stapi since it handles it own pids.... stapi need to be better integrated in oscam dvbapi.
1278 if(selected_api
!= STAPI
)
1281 for(z
= 0; z
< MAX_STREAM_INDICES
; z
++)
1283 ca_index_t idx
= demux
[demux_index
].ECMpids
[oldpid
].index
[z
];
1284 demux
[demux_index
].ECMpids
[oldpid
].index
[z
] = INDEX_INVALID
;
1286 if(idx
!= INDEX_INVALID
) // if in use
1289 for(i
= 0; i
< demux
[demux_index
].STREAMpidcount
; i
++)
1292 // check streams of old disabled ecmpid
1293 if(!demux
[demux_index
].ECMpids
[oldpid
].streams
|| ((demux
[demux_index
].ECMpids
[oldpid
].streams
& (1 << i
)) == (uint
) (1 << i
)))
1295 // check if new ecmpid is using same streams
1296 if(curpid
!= -1 && (!demux
[demux_index
].ECMpids
[curpid
].streams
|| ((demux
[demux_index
].ECMpids
[curpid
].streams
& (1 << i
)) == (uint
) (1 << i
))))
1298 continue; // found same stream on old and new ecmpid -> skip! (and leave it enabled!)
1301 int32_t pidtobestopped
= demux
[demux_index
].STREAMpids
[i
];
1302 int32_t j
, k
, otherdemuxpid
;
1303 ca_index_t otherdemuxidx
;
1305 for(j
= 0; j
< MAX_DEMUX
; j
++) // check other demuxers for same streampid with same index
1307 if(demux
[j
].program_number
== 0) { continue; } // skip empty demuxers
1308 if(demux_index
== j
) { continue; } // skip same demuxer
1309 if(demux
[j
].ca_mask
!= demux
[demux_index
].ca_mask
) { continue;} // skip streampid running on other ca device
1311 otherdemuxpid
= demux
[j
].pidindex
;
1312 if(otherdemuxpid
== -1) { continue; } // Other demuxer not descrambling yet
1315 for(y
= 0; y
< MAX_STREAM_INDICES
; y
++)
1317 otherdemuxidx
= demux
[j
].ECMpids
[otherdemuxpid
].index
[y
];
1318 if(otherdemuxidx
== INDEX_INVALID
|| otherdemuxidx
!= idx
) { continue; } // Other demuxer has no index yet, or index is different
1320 for(k
= 0; k
< demux
[j
].STREAMpidcount
; k
++)
1322 if(!demux
[j
].ECMpids
[otherdemuxpid
].streams
|| ((demux
[j
].ECMpids
[otherdemuxpid
].streams
& (1 << k
)) == (uint
) (1 << k
)))
1324 if(demux
[j
].STREAMpids
[k
] == pidtobestopped
)
1326 continue; // found same streampid enabled with same index on one or more other demuxers -> skip! (and leave it enabled!)
1329 match
= 1; // matching stream found
1336 for(j
= 0; j
< MAX_DEMUX
; j
++)
1338 if(((demux
[demux_index
].ca_mask
& (1 << j
)) == (uint32_t) (1 << j
)))
1340 remove_streampid_from_list(j
, pidtobestopped
, idx
);
1352 if(demux
[demux_index
].demux_fd
[num
].type
== TYPE_EMM
) // If emm type remove from emm filterlist
1354 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);
1356 demux
[demux_index
].demux_fd
[num
].type
= 0;
1357 demux
[demux_index
].demux_fd
[num
].fd
= 0;
1358 return 1; // all ok!
1361 void 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
)
1364 for(o
= 0; o
< maxfilter
; o
++) // check if filter is present
1366 if(demux
[demux_id
].demux_fd
[o
].fd
> 0 &&
1367 demux
[demux_id
].demux_fd
[o
].pid
== pid
&&
1368 demux
[demux_id
].demux_fd
[o
].type
== type
&&
1369 demux
[demux_id
].demux_fd
[o
].filter
[0] == table
&&
1370 demux
[demux_id
].demux_fd
[o
].mask
[0] == mask
1377 memset(filter
, 0, 32);
1382 cs_log_dbg(D_DVBAPI
, "Demuxer %d try to start new filter for caid: %04X, provid: %06X, pid: %04X", demux_id
, caid
, provid
, pid
);
1383 dvbapi_set_filter(demux_id
, selected_api
, pid
, caid
, provid
, filter
, filter
+ 16, timeout
, pidindex
, type
, 0);
1386 void dvbapi_start_sdt_filter(int32_t demux_index
)
1388 dvbapi_start_filter(demux_index
, demux
[demux_index
].pidindex
, 0x11, 0x001, 0x01, 0x42, 0xFF, 0, TYPE_SDT
);
1389 demux
[demux_index
].sdt_filter
= 0;
1392 void dvbapi_start_pat_filter(int32_t demux_index
)
1394 #if defined(WITH_COOLAPI) || defined(WITH_COOLAPI2)
1395 // PAT-Filter breaks API and OSCAM for Coolstream.
1400 dvbapi_start_filter(demux_index
, demux
[demux_index
].pidindex
, 0x00, 0x001, 0x01, 0x00, 0xFF, 0, TYPE_PAT
);
1403 void dvbapi_start_pmt_filter(int32_t demux_index
, int32_t pmt_pid
)
1405 #if defined(WITH_COOLAPI) || defined(WITH_COOLAPI2)
1406 // PMT-Filter breaks API and OSCAM for Coolstream.
1411 uchar filter
[16], mask
[16];
1412 memset(filter
, 0, 16);
1413 memset(mask
, 0, 16);
1416 i2b_buf(2, demux
[demux_index
].program_number
, filter
+ 1); // add srvid to filter since the pid can deliver pmt for multiple srvid
1420 dvbapi_set_filter(demux_index
, selected_api
, pmt_pid
, 0x001, 0x01, filter
, mask
, 0, 0, TYPE_PMT
, 0);
1423 void dvbapi_start_emm_filter(int32_t demux_index
)
1426 if(!demux
[demux_index
].EMMpidcount
)
1429 //if (demux[demux_index].emm_filter)
1433 struct s_csystem_emm_filter
*dmx_filter
= NULL
;
1434 unsigned int filter_count
= 0;
1435 uint16_t caid
, ncaid
;
1438 struct s_reader
*rdr
= NULL
;
1439 struct s_client
*cl
= cur_client();
1440 if(!cl
|| !cl
->aureader_list
)
1443 LL_ITER itr
= ll_iter_create(cl
->aureader_list
);
1444 while((rdr
= ll_iter_next(&itr
)))
1446 if(!(rdr
->grp
& cl
->grp
))
1448 if(rdr
->audisabled
|| !rdr
->enable
|| (!is_network_reader(rdr
) && rdr
->card_status
!= CARD_INSERTED
))
1451 const struct s_cardsystem
*csystem
;
1453 cs_log_dbg(D_DVBAPI
, "Demuxer %d matching reader %s against available emmpids -> START!", demux_index
, rdr
->label
);
1454 for(c
= 0; c
< demux
[demux_index
].EMMpidcount
; c
++)
1456 caid
= ncaid
= demux
[demux_index
].EMMpids
[c
].CAID
;
1459 if(chk_is_betatunnel_caid(caid
) == 2)
1461 ncaid
= tunemm_caid_map(FROM_TO
, caid
, demux
[demux_index
].program_number
);
1463 provid
= demux
[demux_index
].EMMpids
[c
].PROVID
;
1466 match
= emm_reader_match(rdr
, caid
, provid
);
1470 match
= emm_reader_match(rdr
, ncaid
, provid
);
1474 csystem
= get_cardsystem_by_caid(caid
);
1479 csystem
= get_cardsystem_by_caid(ncaid
);
1480 if(csystem
&& csystem
->get_tunemm_filter
)
1482 csystem
->get_tunemm_filter(rdr
, &dmx_filter
, &filter_count
);
1483 cs_log_dbg(D_DVBAPI
, "Demuxer %d setting emm filter for betatunnel: %04X -> %04X", demux_index
, ncaid
, caid
);
1487 cs_log_dbg(D_DVBAPI
, "Demuxer %d cardsystem for emm filter for caid %04X of reader %s not found", demux_index
, ncaid
, rdr
->label
);
1491 else if (csystem
->get_emm_filter
)
1493 csystem
->get_emm_filter(rdr
, &dmx_filter
, &filter_count
);
1498 cs_log_dbg(D_DVBAPI
, "Demuxer %d cardsystem for emm filter for caid %04X of reader %s not found", demux_index
, caid
, rdr
->label
);
1502 for(j
= 0; j
< filter_count
; j
++)
1504 if(dmx_filter
[j
].enabled
== 0)
1508 memset(filter
, 0, sizeof(filter
)); // reset filter
1509 uint32_t usefilterbytes
= 16; // default use all filters
1510 memcpy(filter
, dmx_filter
[j
].filter
, usefilterbytes
);
1511 memcpy(filter
+ 16, dmx_filter
[j
].mask
, usefilterbytes
);
1512 int32_t emmtype
= dmx_filter
[j
].type
;
1514 if(filter
[0] && (((1 << (filter
[0] % 0x80)) & rdr
->b_nano
) && !((1 << (filter
[0] % 0x80)) & rdr
->s_nano
)))
1516 cs_log_dbg(D_DVBAPI
, "Demuxer %d reader %s emmfilter %d/%d blocked by userconfig -> SKIP!", demux_index
, rdr
->label
, j
+1, filter_count
);
1520 if((rdr
->blockemm
& emmtype
) && !(((1 << (filter
[0] % 0x80)) & rdr
->s_nano
) || (rdr
->saveemm
& emmtype
)))
1522 cs_log_dbg(D_DVBAPI
, "Demuxer %d reader %s emmfilter %d/%d blocked by userconfig -> SKIP!", demux_index
, rdr
->label
, j
+1, filter_count
);
1526 if(demux
[demux_index
].EMMpids
[c
].type
& emmtype
)
1528 cs_log_dbg(D_DVBAPI
, "Demuxer %d reader %s emmfilter %d/%d type match -> ENABLE!", demux_index
, rdr
->label
, j
+1, filter_count
);
1529 check_add_emmpid(demux_index
, filter
, c
, emmtype
);
1533 cs_log_dbg(D_DVBAPI
, "Demuxer %d reader %s emmfilter %d/%d type mismatch -> SKIP!", demux_index
, rdr
->label
, j
+1, filter_count
);
1537 // dmx_filter not use below this point;
1538 NULLFREE(dmx_filter
);
1542 cs_log_dbg(D_DVBAPI
, "Demuxer %d matching reader %s against available emmpids -> DONE!", demux_index
, rdr
->label
);
1544 if(demux
[demux_index
].emm_filter
== -1) // first run -1
1546 demux
[demux_index
].emm_filter
= 0;
1548 cs_log_dbg(D_DVBAPI
, "Demuxer %d handles %i emm filters", demux_index
, demux
[demux_index
].emm_filter
);
1551 void dvbapi_add_ecmpid_int(int32_t demux_id
, uint16_t caid
, uint16_t ecmpid
, uint32_t provid
, uint32_t cadata
, char *txt
)
1553 int32_t n
, added
= 0;
1555 int32_t stream
= demux
[demux_id
].STREAMpidcount
- 1;
1556 for(n
= 0; n
< demux
[demux_id
].ECMpidcount
; n
++)
1558 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
)))
1563 if(!demux
[demux_id
].ECMpids
[n
].streams
)
1565 //we already got this caid/ecmpid as global, no need to add the single stream
1566 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
);
1569 demux
[demux_id
].ECMpids
[n
].streams
|= (1 << stream
);
1570 cs_log("Demuxer %d added stream to ecmpid %d CAID: %04X ECM_PID: %04X PROVID: %06X", demux_id
, n
, caid
, ecmpid
, provid
);
1578 if(demux
[demux_id
].ECMpidcount
>= ECM_PIDS
)
1580 cs_log("We reached maximum ECMpids: unable to add to demuxer %d ecmpid %d CAID: %04X ECM_PID: %04X PROVID: %06X %s",
1581 demux_id
, demux
[demux_id
].ECMpidcount
, caid
, ecmpid
, provid
, txt
);
1585 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].ECM_PID
= ecmpid
;
1586 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].CAID
= caid
;
1587 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].PROVID
= provid
;
1588 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].CHID
= 0x10000; // reset CHID
1589 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].checked
= 0;
1590 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].status
= 0;
1591 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].tries
= 0xFE;
1592 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].streams
= 0; // reset streams!
1593 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].irdeto_curindex
= 0xFE; // reset
1594 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].irdeto_maxindex
= 0; // reset
1595 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].irdeto_cycle
= 0xFE; // reset
1596 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].table
= 0;
1597 demux
[demux_id
].ECMpids
[demux
[demux_id
].ECMpidcount
].cadata
= cadata
;
1599 cs_log("Demuxer %d ecmpid %d CAID: %04X ECM_PID: %04X PROVID: %06X %s", demux_id
, demux
[demux_id
].ECMpidcount
, caid
, ecmpid
, provid
, txt
);
1601 // marker to fetch emms early irdeto needs them!
1602 if(caid_is_irdeto(caid
) || (caid_is_dre(caid
) && (provid
== 0x11 || provid
== 0xFE))) { demux
[demux_id
].emmstart
.time
= 1; }
1604 demux
[demux_id
].ECMpidcount
++;
1607 void dvbapi_add_ecmpid(int32_t demux_id
, uint16_t caid
, uint16_t ecmpid
, uint32_t provid
, uint32_t cadata
, char *txt
)
1609 dvbapi_add_ecmpid_int(demux_id
, caid
, ecmpid
, provid
, cadata
, txt
);
1610 struct s_dvbapi_priority
*joinentry
;
1612 for(joinentry
= dvbapi_priority
; joinentry
!= NULL
; joinentry
= joinentry
->next
)
1614 if((joinentry
->type
!= 'j')
1615 || (joinentry
->caid
&& joinentry
->caid
!= caid
)
1616 || (joinentry
->provid
&& joinentry
->provid
!= provid
)
1617 || (joinentry
->ecmpid
&& joinentry
->ecmpid
!= ecmpid
)
1618 || (joinentry
->srvid
&& joinentry
->srvid
!= demux
[demux_id
].program_number
))
1620 cs_log_dbg(D_DVBAPI
, "Join ecmpid %04X@%06X:%04X to %04X@%06X:%04X",
1621 caid
, provid
, ecmpid
, joinentry
->mapcaid
, joinentry
->mapprovid
, joinentry
->mapecmpid
);
1622 dvbapi_add_ecmpid_int(demux_id
, joinentry
->mapcaid
, joinentry
->mapecmpid
, joinentry
->mapprovid
, 0, txt
);
1626 void dvbapi_add_emmpid(int32_t demux_id
, uint16_t caid
, uint16_t emmpid
, uint32_t provid
, uint32_t cadata
, uint8_t type
)
1629 char cadatatext
[40];
1630 cs_strncpy(typetext
, ":", sizeof(typetext
));
1632 if(type
& 0x01) { strcat(typetext
, "UNIQUE:"); }
1633 if(type
& 0x02) { strcat(typetext
, "SHARED:"); }
1634 if(type
& 0x04) { strcat(typetext
, "GLOBAL:"); }
1635 if(type
& 0xF8) { strcat(typetext
, "UNKNOWN:"); }
1637 if(cadata
> 0) snprintf(cadatatext
, 40, " CA DATA %X ", cadata
);
1638 else {cadatatext
[0] = '\t'; cadatatext
[1] = '\0';}
1640 if(caid
== 0x4AE1 && provid
== 0x11 && cadata
== 0) return;
1643 for(i
= 0; i
< demux
[demux_id
].EMMpidcount
; i
++)
1645 if(demux
[demux_id
].EMMpids
[i
].PID
== emmpid
&& demux
[demux_id
].EMMpids
[i
].CAID
== caid
1646 && demux
[demux_id
].EMMpids
[i
].PROVID
== provid
&& demux
[demux_id
].EMMpids
[i
].cadata
== cadata
)
1648 if(!(demux
[demux_id
].EMMpids
[i
].type
&type
)){
1649 demux
[demux_id
].EMMpids
[i
].type
|= type
; // register this emm kind to this emmpid
1650 cs_log_dbg(D_DVBAPI
, "Added to existing emmpid %d additional emmtype %s", demux
[demux_id
].EMMpidcount
- 1, typetext
);
1657 demux
[demux_id
].EMMpids
[demux
[demux_id
].EMMpidcount
].PID
= emmpid
;
1658 demux
[demux_id
].EMMpids
[demux
[demux_id
].EMMpidcount
].CAID
= caid
;
1659 demux
[demux_id
].EMMpids
[demux
[demux_id
].EMMpidcount
].PROVID
= provid
;
1660 demux
[demux_id
].EMMpids
[demux
[demux_id
].EMMpidcount
].type
= type
;
1661 demux
[demux_id
].EMMpids
[demux
[demux_id
].EMMpidcount
++].cadata
= cadata
;
1662 cs_log_dbg(D_DVBAPI
, "Added new emmpid %d CAID: %04X EMM_PID: %04X PROVID: %06X%sTYPE %s", demux
[demux_id
].EMMpidcount
- 1, caid
, emmpid
, provid
,
1663 cadatatext
, typetext
);
1667 cs_log_dbg(D_DVBAPI
, "We reached max emmpids: unable to add new emmpid %d CAID: %04X EMM_PID: %04X PROVID: %06X%sTYPE %s",
1668 demux
[demux_id
].EMMpidcount
- 1, caid
, emmpid
, provid
, cadatatext
, typetext
);
1672 void dvbapi_parse_cat(int32_t demux_id
, uchar
*buf
, int32_t len
)
1674 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
1675 // driver sometimes reports error if too many emm filter
1676 // but adding more ecm filter is no problem
1677 // ... so ifdef here instead of limiting MAX_FILTER
1678 demux
[demux_id
].max_emm_filter
= 14;
1680 if(cfg
.dvbapi_requestmode
== 1)
1682 uint16_t ecm_filter_needed
= 0, n
;
1683 for(n
= 0; n
< demux
[demux_id
].ECMpidcount
; n
++)
1685 if(demux
[demux_id
].ECMpids
[n
].status
> -1)
1686 { ecm_filter_needed
++; }
1688 if(maxfilter
- ecm_filter_needed
<= 0)
1689 { demux
[demux_id
].max_emm_filter
= 0; }
1691 { demux
[demux_id
].max_emm_filter
= maxfilter
- ecm_filter_needed
; }
1695 demux
[demux_id
].max_emm_filter
= maxfilter
- 1;
1700 cs_log_dump_dbg(D_DVBAPI
, buf
, len
, "cat:");
1702 for(i
= 8; i
< (b2i(2, buf
+ 1)&0xFFF) - 1; i
+= buf
[i
+ 1] + 2)
1704 if(buf
[i
] != 0x09) { continue; }
1706 uint16_t caid
= b2i(2, buf
+ i
+ 2);
1707 uint16_t emm_pid
= b2i(2, buf
+ i
+4)&0x1FFF;
1708 uint32_t emm_provider
= 0;
1713 dvbapi_add_emmpid(demux_id
, caid
, emm_pid
, 0, 0, EMM_UNIQUE
| EMM_GLOBAL
);
1714 for(k
= i
+ 7; k
< i
+ buf
[i
+ 1] + 2; k
+= 4)
1716 emm_provider
= b2i(2, buf
+ k
+ 2);
1717 emm_pid
= b2i(2, buf
+ k
)&0xFFF;
1718 dvbapi_add_emmpid(demux_id
, caid
, emm_pid
, emm_provider
, 0, EMM_SHARED
);
1722 for(k
= i
+ 6; k
< i
+ buf
[i
+ 1] + 2; k
+= buf
[k
+ 1] + 2)
1726 emm_provider
= (b2i(3, buf
+ k
+ 2) & 0xFFFFF0); // viaccess fixup last digit is a dont care!
1727 dvbapi_add_emmpid(demux_id
, caid
, emm_pid
, emm_provider
, 0, EMM_UNIQUE
| EMM_SHARED
| EMM_GLOBAL
);
1732 if(buf
[i
+ 1] == 0x07 || buf
[i
+ 1] == 0x0B)
1734 for(k
= i
+ 7; k
< i
+ 7 + buf
[i
+ 6]; k
+= 2)
1736 emm_provider
= b2i(2, buf
+ k
);
1737 dvbapi_add_emmpid(demux_id
, caid
, emm_pid
, emm_provider
, 0, EMM_UNIQUE
| EMM_SHARED
| EMM_GLOBAL
);
1742 dvbapi_add_emmpid(demux_id
, caid
, emm_pid
, emm_provider
, 0, EMM_UNIQUE
| EMM_SHARED
| EMM_GLOBAL
);
1748 if(caid_is_bulcrypt(caid
))
1750 dvbapi_add_emmpid(demux_id
, caid
, emm_pid
, 0, 0, EMM_UNIQUE
| EMM_SHARED
| EMM_GLOBAL
);
1754 emm_provider
= (uint32_t)buf
[i
+6];
1755 if(buf
[i
+6] == 0xFE)
1757 dvbapi_add_emmpid(demux_id
, caid
, emm_pid
, emm_provider
, 0x102, EMM_GLOBAL
);
1761 uint32_t cadata
= 0;
1762 if(buf
[i
+1] == 0x0A)
1764 cadata
= (buf
[i
+8] << 24) | (buf
[i
+9] << 16) | (buf
[i
+10] << 8) | buf
[i
+11];
1766 dvbapi_add_emmpid(demux_id
, caid
, emm_pid
, emm_provider
, cadata
, EMM_UNIQUE
| EMM_SHARED
| EMM_GLOBAL
);
1770 dvbapi_add_emmpid(demux_id
, caid
, emm_pid
, 0, 0, EMM_UNIQUE
| EMM_SHARED
| EMM_GLOBAL
);
1777 static pthread_mutex_t lockindex
= PTHREAD_MUTEX_INITIALIZER
;
1779 ca_index_t
dvbapi_get_descindex(int32_t demux_index
, int32_t pid
, int32_t stream_id
)
1781 int32_t i
, j
, k
, fail
= 1;
1785 if(cfg
.dvbapi_boxtype
== BOXTYPE_NEUMO
)
1788 sscanf(demux
[demux_index
].pmt_file
, "pmt%3d.tmp", &tmp_idx
);
1789 return (ca_index_t
)tmp_idx
;
1792 SAFE_MUTEX_LOCK(&lockindex
); // to avoid race when readers become responsive!
1794 while(fail
&& idx
<= INDEX_MAX
)
1797 for(i
= 0; i
< MAX_DEMUX
&& !fail
&& idx
<= INDEX_MAX
; i
++)
1799 if(demux
[i
].program_number
== 0) { continue; } // skip empty demuxers
1801 if(demux
[i
].ca_mask
!= demux
[demux_index
].ca_mask
&& (!(cfg
.dvbapi_boxtype
== BOXTYPE_PC
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)))
1803 continue; // skip demuxer using other ca device
1806 for(j
= 0; j
< demux
[i
].ECMpidcount
&& !fail
; j
++) // search for new unique index
1808 for(k
= 0; k
< MAX_STREAM_INDICES
; k
++)
1810 if(demux
[i
].ECMpids
[j
].index
[k
] == idx
)
1820 if(cfg
.dvbapi_boxtype
== BOXTYPE_PC
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)
1822 if(idx
> INDEX_MAX_NET
)
1824 idx
= INDEX_INVALID
;
1829 if(idx
> INDEX_MAX_LOCAL
)
1831 idx
= INDEX_INVALID
;
1835 demux
[demux_index
].ECMpids
[pid
].index
[stream_id
] = idx
;
1836 SAFE_MUTEX_UNLOCK(&lockindex
); // and release it!
1840 void dvbapi_set_pid(int32_t demux_id
, int32_t num
, ca_index_t idx
, bool enable
, bool use_des
, uint32_t msgid
)
1842 int32_t i
, currentfd
;
1843 uint16_t streampid
= demux
[demux_id
].STREAMpids
[num
];
1844 ca_index_t newidx
= 0, curidx
;
1847 if(demux
[demux_id
].pidindex
== -1 && enable
) return; // no current pid on enable? --> exit
1849 switch(selected_api
)
1851 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
1853 if(!enable
) idx
= INDEX_INVALID
;
1854 stapi_set_pid(demux_id
, num
, idx
, streampid
, demux
[demux_id
].pmt_file
); // only used to disable pids!!!
1857 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
1862 for(i
= 0; i
< MAX_DEMUX
; i
++)
1864 newidx
= INDEX_INVALID
, curidx
= idx
;
1865 if(((demux
[demux_id
].ca_mask
& (1 << i
)) == (uint32_t) (1 << i
)))
1867 uint32_t action
= 0;
1869 action
= update_streampid_list(i
, streampid
, curidx
, use_des
);
1872 action
= remove_streampid_from_list(i
, streampid
, curidx
);
1875 if(action
!= NO_STREAMPID_LISTED
&& action
!= INVALID_STREAMPID_INDEX
&& action
!= FOUND_STREAMPID_INDEX
&& action
!= ADDED_STREAMPID_INDEX
&& action
!= REMOVED_STREAMPID_INDEX
)
1877 // removed last of this streampid on ca? -> disable this pid with -1 on this ca
1878 if((action
== REMOVED_STREAMPID_LASTINDEX
|| action
== FIRST_STREAMPID_INDEX
) && (is_ca_used(i
, streampid
) == INDEX_INVALID
)) curidx
= DVBAPI_INDEX_DISABLE
;
1880 // removed index of streampid that is used to decode on ca -> get a fresh one
1881 if(action
== REMOVED_DECODING_STREAMPID_INDEX
|| action
== FIRST_STREAMPID_INDEX
)
1883 newidx
= is_ca_used(i
, streampid
); // get an active index for this pid and enable it on ca device
1884 curidx
= DVBAPI_INDEX_DISABLE
;
1887 while (curidx
!= INDEX_INVALID
|| newidx
!= INDEX_INVALID
)
1889 memset(&ca_pid2
, 0, sizeof(ca_pid2
));
1890 ca_pid2
.pid
= streampid
;
1892 if(curidx
!= INDEX_INVALID
)
1894 (curidx
== DVBAPI_INDEX_DISABLE
) ? (ca_pid2
.index
= -1) : (ca_pid2
.index
= curidx
);
1895 cs_log_dbg(D_DVBAPI
, "Demuxer %d %s stream %d pid=0x%04x index=%d on ca%d", demux_id
,
1896 ((enable
&& curidx
!= DVBAPI_INDEX_DISABLE
) ? "enable" : "disable"), num
+ 1, ca_pid2
.pid
, ca_pid2
.index
, i
);
1897 curidx
= INDEX_INVALID
; // flag this index as handled
1899 else if (newidx
!= INDEX_INVALID
)
1901 (newidx
== DVBAPI_INDEX_DISABLE
) ? (ca_pid2
.index
= -1) : (ca_pid2
.index
= newidx
);
1903 cs_log_dbg(D_DVBAPI
, "Demuxer %d %s stream %d pid=0x%04x by index=%d on ca%d", demux_id
,
1904 ((enable
&& action
== FIRST_STREAMPID_INDEX
) ? "enable" : "takeover"), num
+ 1, ca_pid2
.pid
, ca_pid2
.index
, i
);
1906 newidx
= INDEX_INVALID
; // flag this takeover / new index as handled
1909 if(use_des
&& cfg
.dvbapi_extended_cw_api
== 2 && ca_pid2
.index
!= -1)
1911 ca_pid2
.index
|= 0x100;
1914 if(cfg
.dvbapi_boxtype
== BOXTYPE_PC
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)
1915 dvbapi_net_send(DVBAPI_CA_SET_PID
, demux
[demux_id
].socket_fd
, msgid
, demux_id
, -1 /*unused*/, (unsigned char *) &ca_pid2
, NULL
, NULL
, demux
[demux_id
].client_proto_version
);
1918 currentfd
= ca_fd
[i
];
1921 currentfd
= dvbapi_open_device(1, i
, demux
[demux_id
].adapter_index
);
1922 ca_fd
[i
] = currentfd
; // save fd of this ca
1926 if(dvbapi_ioctl(currentfd
, CA_SET_PID
, &ca_pid2
) == -1)
1928 cs_log_dbg(D_TRACE
| D_DVBAPI
,"CA_SET_PID ioctl error (errno=%d %s)", errno
, strerror(errno
));
1929 remove_streampid_from_list(i
, ca_pid2
.pid
, INDEX_DISABLE_ALL
);
1931 ca_index_t result
= is_ca_used(i
,0); // check if in use by any pid
1932 if(result
== INDEX_INVALID
)
1934 cs_log_dbg(D_DVBAPI
, "Demuxer %d close now unused CA%d device", demux_id
, i
);
1935 int32_t ret
= close(currentfd
);
1936 if(ret
< 0) { cs_log("ERROR: Could not close demuxer fd (errno=%d %s)", errno
, strerror(errno
)); }
1937 currentfd
= ca_fd
[i
] = 0;
1950 void dvbapi_stop_all_descrambling(uint32_t msgid
)
1953 for(j
= 0; j
< MAX_DEMUX
; j
++)
1955 if(demux
[j
].program_number
== 0) { continue; }
1956 dvbapi_stop_descrambling(j
, msgid
);
1960 void dvbapi_stop_all_emm_sdt_filtering(uint32_t msgid
)
1963 for(j
= 0; j
< MAX_DEMUX
; j
++)
1965 if(demux
[j
].program_number
== 0) { continue; }
1966 dvbapi_stop_filter(j
, TYPE_EMM
, msgid
);
1967 dvbapi_stop_filter(j
, TYPE_SDT
, msgid
);
1968 demux
[j
].emm_filter
= -1;
1973 void dvbapi_stop_descrambling(int32_t demux_id
, uint32_t msgid
)
1976 if(demux
[demux_id
].program_number
== 0) { return; }
1977 char channame
[CS_SERVICENAME_SIZE
];
1978 i
= demux
[demux_id
].pidindex
;
1979 if(i
< 0) { i
= 0; }
1980 demux
[demux_id
].pidindex
= -1; // no ecmpid is to be descrambling since we start stop descrambling!
1981 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
));
1982 cs_log("Demuxer %d stop descrambling program number %04X (%s)", demux_id
, demux
[demux_id
].program_number
, channame
);
1984 dvbapi_stop_filter(demux_id
, TYPE_EMM
, msgid
);
1985 dvbapi_stop_filter(demux_id
, TYPE_SDT
, msgid
);
1986 dvbapi_stop_filter(demux_id
, TYPE_PAT
, msgid
);
1987 dvbapi_stop_filter(demux_id
, TYPE_PMT
, msgid
);
1989 for(i
= 0; i
< demux
[demux_id
].ECMpidcount
&& demux
[demux_id
].ECMpidcount
> 0; i
++)
1991 for(j
= 0; j
< MAX_STREAM_INDICES
; j
++)
1993 if(demux
[demux_id
].ECMpids
[i
].index
[j
] == INDEX_INVALID
) continue;
1996 for(z
= 0; z
< demux
[demux_id
].STREAMpidcount
; z
++)
1998 dvbapi_set_pid(demux_id
, z
, demux
[demux_id
].ECMpids
[i
].index
[j
], false, false, msgid
); // disable streampid
2000 demux
[demux_id
].ECMpids
[i
].index
[j
] = INDEX_INVALID
;
2003 dvbapi_stop_filter(demux_id
, TYPE_ECM
, msgid
);
2005 pthread_mutex_destroy(&demux
[demux_id
].answerlock
);
2006 memset(&demux
[demux_id
], 0 , sizeof(DEMUXTYPE
));
2007 SAFE_MUTEX_INIT(&demux
[demux_id
].answerlock
, NULL
);
2009 for(i
= 0; i
< ECM_PIDS
; i
++)
2011 for(j
= 0; j
< MAX_STREAM_INDICES
; j
++)
2013 demux
[demux_id
].ECMpids
[i
].index
[j
] = INDEX_INVALID
;
2017 demux
[demux_id
].pidindex
= -1;
2018 demux
[demux_id
].curindex
= -1;
2019 if (!cfg
.dvbapi_listenport
&& cfg
.dvbapi_boxtype
!= BOXTYPE_PC_NODMX
)
2020 unlink(ECMINFO_FILE
);
2024 int32_t dvbapi_start_descrambling(int32_t demux_id
, int32_t pid
, int8_t checked
, uint32_t msgid
)
2026 int32_t started
= 0; // in case ecmfilter started = 1
2027 int32_t fake_ecm
= 0;
2029 struct s_reader
*rdr
;
2030 if(!(er
= get_ecmtask())) { return started
; }
2031 demux
[demux_id
].ECMpids
[pid
].checked
= checked
+ 1; // mark this pid as checked!
2033 struct s_dvbapi_priority
*p
;
2034 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
)
2037 || (p
->caid
&& p
->caid
!= demux
[demux_id
].ECMpids
[pid
].CAID
)
2038 || (p
->provid
&& p
->provid
!= demux
[demux_id
].ECMpids
[pid
].PROVID
)
2039 || (p
->ecmpid
&& p
->ecmpid
!= demux
[demux_id
].ECMpids
[pid
].ECM_PID
)
2040 || (p
->srvid
&& p
->srvid
!= demux
[demux_id
].program_number
)
2041 || (p
->pidx
&& p
->pidx
-1 != pid
)
2042 || (p
->cadata
&& p
->cadata
!= demux
[demux_id
].ECMpids
[pid
].cadata
))
2044 // if found chid and first run apply chid filter, on forced pids always apply!
2045 if(p
->type
== 'p' && p
->chid
< 0x10000 && (demux
[demux_id
].ECMpids
[pid
].checked
== 1 || (p
&& p
->force
)))
2047 if(demux
[demux_id
].ECMpids
[pid
].CHID
< 0x10000) // channelcache delivered chid
2049 er
->chid
= demux
[demux_id
].ECMpids
[pid
].CHID
;
2053 er
->chid
= p
->chid
; // no channelcache or no chid in use, so use prio chid
2054 demux
[demux_id
].ECMpids
[pid
].CHID
= p
->chid
;
2056 //cs_log("********* CHID %04X **************", demux[demux_id].ECMpids[pid].CHID);
2057 break; // we only accept one!
2061 if(demux
[demux_id
].ECMpids
[pid
].CHID
< 0x10000) // channelcache delivered chid
2063 er
->chid
= demux
[demux_id
].ECMpids
[pid
].CHID
;
2065 else // no channelcache or no chid in use
2068 demux
[demux_id
].ECMpids
[pid
].CHID
= 0x10000;
2072 er
->srvid
= demux
[demux_id
].program_number
;
2073 er
->caid
= demux
[demux_id
].ECMpids
[pid
].CAID
;
2074 er
->pid
= demux
[demux_id
].ECMpids
[pid
].ECM_PID
;
2075 er
->prid
= demux
[demux_id
].ECMpids
[pid
].PROVID
;
2076 er
->vpid
= demux
[demux_id
].ECMpids
[pid
].VPID
;
2077 er
->pmtpid
= demux
[demux_id
].pmtpid
;
2078 er
->onid
= demux
[demux_id
].onid
;
2082 cs_strncpy(er
->dev_name
, dev_list
[demux
[demux_id
].dev_index
].name
, sizeof(dev_list
[demux
[demux_id
].dev_index
].name
));
2087 for(rdr
= first_active_reader
; rdr
!= NULL
; rdr
= rdr
->next
)
2089 int8_t match
= matching_reader(er
, rdr
); // check for matching reader
2090 int64_t gone
= comp_timeb(&now
, &rdr
->emm_last
);
2091 if(gone
> 3600*1000 && rdr
->needsemmfirst
&& caid_is_irdeto(er
->caid
))
2093 cs_log("Warning reader %s received no emms for the last %d seconds -> skip, this reader needs emms first!", rdr
->label
,
2095 continue; // skip this card needs to process emms first before it can be used for descramble
2097 if(p
&& p
->force
) { match
= 1; } // forced pid always started!
2099 if(!match
) // if this reader does not match, check betatunnel for it
2100 match
= lb_check_auto_betatunnel(er
, rdr
);
2102 if(!match
&& chk_is_betatunnel_caid(er
->caid
)) // these caids might be tunneled invisible by peers
2103 { match
= 1; } // so make it a match to try it!
2105 if(config_enabled(CS_CACHEEX
) && (!match
&& (cacheex_is_match_alias(dvbapi_client
, er
)))) // check if cache-ex is matching
2107 match
= 1; // so make it a match to try it!
2110 // BISS or FAKE CAID
2111 // ecm stream pid is fake, so send out one fake ecm request
2112 // special treatment: if we asked the cw first without starting a filter the cw request will be killed due to no ecmfilter started
2113 if(caid_is_fake(demux
[demux_id
].ECMpids
[pid
].CAID
) || caid_is_biss(demux
[demux_id
].ECMpids
[pid
].CAID
))
2117 er
->ecm
[0] = 0x80; // to pass the cache check it must be 0x80 or 0x81
2120 i2b_buf(2, er
->srvid
, er
->ecm
+ 3);
2122 for(j
= 0, n
= 5; j
< demux
[demux_id
].STREAMpidcount
; j
++, n
+= 2)
2124 i2b_buf(2, demux
[demux_id
].STREAMpids
[j
], er
->ecm
+ n
);
2129 cs_log("Demuxer %d trying to descramble PID %d CAID %04X PROVID %06X ECMPID %04X ANY CHID PMTPID %04X VPID %04X", demux_id
, pid
,
2130 demux
[demux_id
].ECMpids
[pid
].CAID
, demux
[demux_id
].ECMpids
[pid
].PROVID
, demux
[demux_id
].ECMpids
[pid
].ECM_PID
,
2131 demux
[demux_id
].pmtpid
, demux
[demux_id
].ECMpids
[pid
].VPID
);
2133 demux
[demux_id
].curindex
= pid
; // set current pid to the fresh started one
2135 dvbapi_start_filter(demux_id
, pid
, demux
[demux_id
].ECMpids
[pid
].ECM_PID
, demux
[demux_id
].ECMpids
[pid
].CAID
,
2136 demux
[demux_id
].ECMpids
[pid
].PROVID
, 0x80, 0xF0, 3000, TYPE_ECM
);
2139 request_cw(dvbapi_client
, er
, demux_id
, 0); // do not register ecm since this try!
2141 break; // we started an ecmfilter so stop looking for next matching reader!
2143 if(match
) // if matching reader found check for irdeto cas if local irdeto card check if it received emms in last 60 minutes
2146 if(caid_is_irdeto(er
->caid
)) // irdeto cas init irdeto_curindex to wait for first index (00)
2148 if(demux
[demux_id
].ECMpids
[pid
].irdeto_curindex
== 0xFE) { demux
[demux_id
].ECMpids
[pid
].irdeto_curindex
= 0x00; }
2151 if(p
&& p
->chid
< 0x10000) // do we prio a certain chid?
2153 cs_log("Demuxer %d trying to descramble PID %d CAID %04X PROVID %06X ECMPID %04X CHID %04X PMTPID %04X VPID %04X", demux_id
, pid
,
2154 demux
[demux_id
].ECMpids
[pid
].CAID
, demux
[demux_id
].ECMpids
[pid
].PROVID
, demux
[demux_id
].ECMpids
[pid
].ECM_PID
,
2155 demux
[demux_id
].ECMpids
[pid
].CHID
, demux
[demux_id
].pmtpid
, demux
[demux_id
].ECMpids
[pid
].VPID
);
2159 cs_log("Demuxer %d trying to descramble PID %d CAID %04X PROVID %06X ECMPID %04X ANY CHID PMTPID %04X VPID %04X", demux_id
, pid
,
2160 demux
[demux_id
].ECMpids
[pid
].CAID
, demux
[demux_id
].ECMpids
[pid
].PROVID
, demux
[demux_id
].ECMpids
[pid
].ECM_PID
,
2161 demux
[demux_id
].pmtpid
, demux
[demux_id
].ECMpids
[pid
].VPID
);
2164 demux
[demux_id
].curindex
= pid
; // set current pid to the fresh started one
2166 dvbapi_start_filter(demux_id
, pid
, demux
[demux_id
].ECMpids
[pid
].ECM_PID
, demux
[demux_id
].ECMpids
[pid
].CAID
,
2167 demux
[demux_id
].ECMpids
[pid
].PROVID
, 0x80, 0xF0, 3000, TYPE_ECM
);
2169 break; // we started an ecmfilter so stop looking for next matching reader!
2172 if(demux
[demux_id
].curindex
!= pid
)
2174 cs_log("Demuxer %d impossible to descramble PID %d CAID %04X PROVID %06X ECMPID %04X PMTPID %04X (NO MATCHING READER)", demux_id
, pid
,
2175 demux
[demux_id
].ECMpids
[pid
].CAID
, demux
[demux_id
].ECMpids
[pid
].PROVID
, demux
[demux_id
].ECMpids
[pid
].ECM_PID
, demux
[demux_id
].pmtpid
);
2176 demux
[demux_id
].ECMpids
[pid
].checked
= 4; // flag this pid as checked
2177 demux
[demux_id
].ECMpids
[pid
].status
= -1; // flag this pid as unusable
2178 dvbapi_edit_channel_cache(demux_id
, pid
, 0); // remove this pid from channelcache
2180 if(!fake_ecm
) { NULLFREE(er
); }
2184 struct s_dvbapi_priority
*dvbapi_check_prio_match_emmpid(int32_t demux_id
, uint16_t caid
, uint32_t provid
, char type
)
2186 struct s_dvbapi_priority
*p
;
2189 uint16_t ecm_pid
= 0;
2190 for(i
= 0; i
< demux
[demux_id
].ECMpidcount
; i
++)
2192 if((demux
[demux_id
].ECMpids
[i
].CAID
== caid
) && (demux
[demux_id
].ECMpids
[i
].PROVID
== provid
))
2194 ecm_pid
= demux
[demux_id
].ECMpids
[i
].ECM_PID
;
2202 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
)
2205 || (p
->caid
&& p
->caid
!= caid
)
2206 || (p
->provid
&& p
->provid
!= provid
)
2207 || (p
->ecmpid
&& p
->ecmpid
!= ecm_pid
)
2208 || (p
->srvid
&& p
->srvid
!= demux
[demux_id
].program_number
)
2209 || (p
->pidx
&& p
->pidx
-1 !=i
)
2210 || (p
->type
== 'i' && (p
->chid
< 0x10000)))
2217 struct s_dvbapi_priority
*dvbapi_check_prio_match(int32_t demux_id
, int32_t pidindex
, char type
)
2219 if(!dvbapi_priority
)
2223 struct s_dvbapi_priority
*p
;
2224 struct s_ecmpids
*ecmpid
= &demux
[demux_id
].ECMpids
[pidindex
];
2226 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
)
2229 || (p
->caid
&& p
->caid
!= ecmpid
->CAID
)
2230 || (p
->provid
&& p
->provid
!= ecmpid
->PROVID
)
2231 || (p
->ecmpid
&& p
->ecmpid
!= ecmpid
->ECM_PID
)
2232 || (p
->srvid
&& p
->srvid
!= demux
[demux_id
].program_number
)
2233 || (p
->pidx
&& p
->pidx
-1 != pidindex
)
2234 || (p
->chid
< 0x10000 && p
->chid
!= ecmpid
->CHID
))
2241 void dvbapi_process_emm(int32_t demux_index
, int32_t filter_num
, unsigned char *buffer
, uint32_t len
)
2245 struct s_emm_filter
*filter
= get_emmfilter_by_filternum(demux_index
, filter_num
+1); // 0 is used for pending emmfilters, so everything increase 1
2249 cs_log_dbg(D_DVBAPI
, "Demuxer %d Filter %d no filter matches -> SKIP!", demux_index
, filter_num
+1);
2253 uint32_t provider
= filter
->provid
;
2254 uint16_t caid
= filter
->caid
;
2256 struct s_dvbapi_priority
*mapentry
= dvbapi_check_prio_match_emmpid(filter
->demux_id
, filter
->caid
, filter
->provid
, 'm');
2259 cs_log_dbg(D_DVBAPI
, "Demuxer %d mapping EMM from %04X@%06X to %04X@%06X", demux_index
, caid
, provider
, mapentry
->mapcaid
,
2260 mapentry
->mapprovid
);
2261 caid
= mapentry
->mapcaid
;
2262 provider
= mapentry
->mapprovid
;
2265 memset(&epg
, 0, sizeof(epg
));
2267 i2b_buf(2, caid
, epg
.caid
);
2268 i2b_buf(4, provider
, epg
.provid
);
2270 epg
.emmlen
= len
> sizeof(epg
.emm
) ? sizeof(epg
.emm
) : len
;
2271 memcpy(epg
.emm
, buffer
, epg
.emmlen
);
2273 if(config_enabled(READER_IRDETO
) && chk_is_betatunnel_caid(caid
) == 2)
2275 uint16_t ncaid
= tunemm_caid_map(FROM_TO
, caid
, demux
[demux_index
].program_number
);
2278 irdeto_add_emm_header(&epg
);
2279 i2b_buf(2, ncaid
, epg
.caid
);
2283 do_emm(dvbapi_client
, &epg
);
2286 void dvbapi_read_priority(void)
2289 char token
[128], str1
[128];
2291 int32_t i
, ret
, count
= 0;
2293 const char *cs_prio
= "oscam.dvbapi";
2295 fp
= fopen(get_config_filename(token
, sizeof(token
), cs_prio
), "r");
2299 cs_log_dbg(D_DVBAPI
, "ERROR: Can't open priority file %s", token
);
2305 cs_log_dbg(D_DVBAPI
, "reread priority file %s", cs_prio
);
2306 struct s_dvbapi_priority
*o
, *p
;
2307 for(p
= dvbapi_priority
; p
!= NULL
; p
= o
)
2312 dvbapi_priority
= NULL
;
2315 while(fgets(token
, sizeof(token
), fp
))
2317 // Ignore comments and empty lines
2318 if(token
[0] == '#' || token
[0] == '/' || token
[0] == '\n' || token
[0] == '\r' || token
[0] == '\0')
2320 if(strlen(token
) > 100) { continue; }
2322 memset(str1
, 0, 128);
2324 for(i
= 0; i
< (int)strlen(token
) && token
[i
] == ' '; i
++) { ; }
2325 if(i
== (int)strlen(token
) - 1) //empty line or all spaces
2328 for(i
= 0; i
< (int)strlen(token
); i
++)
2336 for(i
= 0; i
< (int)strlen(token
); i
++)
2338 if((token
[i
] == ':' || token
[i
] == ' ') && token
[i
+ 1] == ':') // if "::" or " :"
2340 memmove(token
+ i
+ 2, token
+ i
+ 1, strlen(token
) - i
+ 1); //insert extra position
2341 token
[i
+ 1] = '0'; //and fill it with NULL
2343 if(token
[i
] == '#' || token
[i
] == '/')
2351 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
2352 uint32_t disablefilter
= 0;
2353 ret
= sscanf(trim(token
), "%c: %63s %63s %d", &type
, str1
, str1
+ 64, &disablefilter
);
2355 ret
= sscanf(trim(token
), "%c: %63s %63s", &type
, str1
, str1
+ 64);
2357 type
= tolower((uchar
)type
);
2359 if(ret
< 1 || (type
!= 'p' && type
!= 'i' && type
!= 'm' && type
!= 'd' && type
!= 's' && type
!= 'l'
2360 && type
!= 'j' && type
!= 'a' && type
!= 'x'))
2362 //fprintf(stderr, "Warning: line containing %s in %s not recognized, ignoring line\n", token, cs_prio);
2363 //fprintf would issue the warning to the command line, which is more consistent with other config warnings
2364 //however it takes OSCam a long time (>4 seconds) to reach this part of the program, so the warnings are reaching tty rather late
2365 //which leads to confusion. So send the warnings to log file instead
2366 cs_log_dbg(D_DVBAPI
, "WARN: line containing %s in %s not recognized, ignoring line\n", token
, cs_prio
);
2370 struct s_dvbapi_priority
*entry
;
2371 if(!cs_malloc(&entry
, sizeof(struct s_dvbapi_priority
)))
2374 if(ret
< 0) { cs_log("ERROR: Could not close oscam.dvbapi fd (errno=%d %s)", errno
, strerror(errno
)); }
2383 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
2386 strncpy(entry
->devname
, str1
, 29);
2387 strncpy(entry
->pmtfile
, str1
+ 64, 29);
2389 entry
->disablefilter
= disablefilter
;
2391 cs_log_dbg(D_DVBAPI
, "stapi prio: ret=%d | %c: %s %s | disable %d",
2392 ret
, type
, entry
->devname
, entry
->pmtfile
, disablefilter
);
2394 if(!dvbapi_priority
)
2396 dvbapi_priority
= entry
;
2400 struct s_dvbapi_priority
*p
;
2401 for(p
= dvbapi_priority
; p
->next
!= NULL
; p
= p
->next
) { ; }
2410 uint32_t caid
= 0, provid
= 0, srvid
= 0, ecmpid
= 0, cadata
= 0;;
2411 uint32_t chid
= 0x10000; //chid=0 is a valid chid
2412 ret
= sscanf(str1
, "%4x:%6x:%33[^:]:%4x:%4x:%8x"SCNx16
, &caid
, &provid
, c_srvid
, &ecmpid
, &chid
, &cadata
);
2415 cs_log("Error in oscam.dvbapi: ret=%d | %c: %04X %06X %s %04X %04X",
2416 ret
, type
, caid
, provid
, c_srvid
, ecmpid
, chid
);
2417 continue; // skip this entry!
2421 cs_log_dbg(D_DVBAPI
, "Parsing rule: ret=%d | %c: %04X %06X %s %04X %04X %04X",
2422 ret
, type
, caid
, provid
, c_srvid
, ecmpid
, chid
, cadata
);
2426 entry
->provid
= provid
;
2427 entry
->ecmpid
= ecmpid
;
2429 entry
->cadata
= cadata
;
2431 uint32_t delay
= 0, force
= 0, mapcaid
= 0, mapprovid
= 0, mapecmpid
= 0, pidx
= 0;
2435 ret
= sscanf(str1
+ 64, "%1d", &pidx
);
2436 entry
->pidx
= pidx
+1;
2437 if(ret
< 1) entry
->pidx
= 0;
2440 sscanf(str1
+ 64, "%4d", &delay
);
2441 entry
->delay
= delay
;
2444 entry
->delay
= dyn_word_atob(str1
+ 64);
2445 if(entry
->delay
== -1) { entry
->delay
= 0; }
2448 ret
= sscanf(str1
+ 64, "%1d:%1d", &force
, &pidx
);
2449 entry
->force
= force
;
2450 entry
->pidx
= pidx
+1;
2451 if(ret
< 2) entry
->pidx
= 0;
2454 sscanf(str1
+ 64, "%4x:%6x", &mapcaid
, &mapprovid
);
2455 if(!mapcaid
) { mapcaid
= 0xFFFF; }
2456 entry
->mapcaid
= mapcaid
;
2457 entry
->mapprovid
= mapprovid
;
2461 sscanf(str1
+ 64, "%4x:%6x:%4x", &mapcaid
, &mapprovid
, &mapecmpid
);
2462 if(!mapcaid
) { mapcaid
= 0xFFFF; }
2463 entry
->mapcaid
= mapcaid
;
2464 entry
->mapprovid
= mapprovid
;
2465 entry
->mapecmpid
= mapecmpid
;
2469 if(c_srvid
[0] == '=')
2471 struct s_srvid
*this;
2473 for(i
= 0; i
< 16; i
++)
2474 for(this = cfg
.srvid
[i
]; this != NULL
; this = this->next
)
2476 if(this->name
&& strcmp(this->name
, c_srvid
+ 1) == 0)
2478 struct s_dvbapi_priority
*entry2
;
2479 if(!cs_malloc(&entry2
, sizeof(struct s_dvbapi_priority
)))
2481 memcpy(entry2
, entry
, sizeof(struct s_dvbapi_priority
));
2482 entry2
->srvid
= this->srvid
;
2483 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
);
2485 if(!dvbapi_priority
)
2487 dvbapi_priority
= entry2
;
2491 struct s_dvbapi_priority
*p
;
2492 for(p
= dvbapi_priority
; p
->next
!= NULL
; p
= p
->next
) { ; }
2502 sscanf(c_srvid
, "%4x", &srvid
);
2503 entry
->srvid
= srvid
;
2505 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
);
2507 if(!dvbapi_priority
)
2509 dvbapi_priority
= entry
;
2513 struct s_dvbapi_priority
*p
;
2514 for(p
= dvbapi_priority
; p
->next
!= NULL
; p
= p
->next
) { ; }
2519 cs_log_dbg(D_DVBAPI
, "Read %d entries from %s", count
, cs_prio
);
2522 if(ret
< 0) { cs_log("ERROR: Could not close oscam.dvbapi fd (errno=%d %s)", errno
, strerror(errno
)); }
2526 void dvbapi_resort_ecmpids(int32_t demux_index
)
2528 int32_t n
, cache
= 0, matching_done
= 0, found
= -1, match_reader_count
= 0, total_reader
= 0;
2529 uint16_t btun_caid
= 0;
2530 struct timeb start
,end
;
2532 for(n
= 0; n
< demux
[demux_index
].ECMpidcount
; n
++)
2534 demux
[demux_index
].ECMpids
[n
].status
= 0;
2535 demux
[demux_index
].ECMpids
[n
].checked
= 0;
2536 demux
[demux_index
].ECMpids
[n
].irdeto_curindex
= 0xFE;
2537 demux
[demux_index
].ECMpids
[n
].irdeto_maxindex
= 0;
2538 demux
[demux_index
].ECMpids
[n
].irdeto_cycle
= 0xFE;
2539 demux
[demux_index
].ECMpids
[n
].tries
= 0xFE;
2540 demux
[demux_index
].ECMpids
[n
].table
= 0;
2543 demux
[demux_index
].max_status
= 0;
2544 demux
[demux_index
].curindex
= -1;
2545 demux
[demux_index
].pidindex
= -1;
2548 struct s_reader
*rdr
;
2550 int32_t p_order
= demux
[demux_index
].ECMpidcount
+1;
2551 struct s_dvbapi_priority
*prio
;
2553 // handle prio order in oscam.dvbapi + ignore all chids
2555 for(rdr
= first_active_reader
; rdr
; rdr
= rdr
->next
)
2557 total_reader
++; // only need to calculate once!
2561 if(!cs_malloc(&er
, sizeof(ECM_REQUEST
)))
2564 for(prio
= dvbapi_priority
; prio
!= NULL
; prio
= prio
->next
)
2566 if(prio
->type
!= 'p' && prio
->type
!= 'i' )
2568 for(n
= 0; n
< demux
[demux_index
].ECMpidcount
; n
++)
2570 if(demux
[demux_index
].ECMpids
[n
].status
== -1) continue; // skip ignores!
2571 er
->caid
= er
->ocaid
= demux
[demux_index
].ECMpids
[n
].CAID
;
2572 er
->prid
= demux
[demux_index
].ECMpids
[n
].PROVID
;
2573 er
->pid
= demux
[demux_index
].ECMpids
[n
].ECM_PID
;
2574 er
->srvid
= demux
[demux_index
].program_number
;
2575 er
->client
= cur_client();
2576 btun_caid
= chk_on_btun(SRVID_MASK
, er
->client
, er
);
2577 if(prio
->type
== 'p' && btun_caid
)
2579 er
->caid
= btun_caid
;
2582 if(prio
->caid
&& (prio
->caid
!= er
->caid
&& prio
->caid
!= er
->ocaid
)) { continue; }
2583 if(prio
->provid
&& prio
->provid
!= er
->prid
) { continue; }
2584 if(prio
->srvid
&& prio
->srvid
!= er
->srvid
) { continue; }
2585 if(prio
->ecmpid
&& prio
->ecmpid
!= er
->pid
) { continue; }
2586 if(prio
->pidx
&& prio
->pidx
-1 != n
) { continue; }
2588 if(prio
->type
== 'p') // check for prio
2590 if(prio
->cadata
!= 0 && prio
->cadata
!= demux
[demux_index
].ECMpids
[n
].cadata
) { continue; }
2591 if(prio
->chid
< 0x10000) { demux
[demux_index
].ECMpids
[n
].CHID
= prio
->chid
; }
2595 for(j
= 0; j
< demux
[demux_index
].ECMpidcount
; j
++)
2597 demux
[demux_index
].ECMpids
[j
].status
= -1;
2599 demux
[demux_index
].ECMpids
[n
].status
= 1;
2600 demux
[demux_index
].ECMpids
[n
].checked
= 0;
2601 demux
[demux_index
].max_status
= 1;
2602 demux
[demux_index
].max_emm_filter
= maxfilter
- 1;
2603 cs_log_dbg(D_DVBAPI
, "Demuxer %d prio forced%s ecmpid %d %04X@%06X:%04X:%04X (file)", demux_index
,
2604 ((prio
->caid
== er
->caid
&& prio
->caid
!= er
->ocaid
) ? " betatunneled" : ""), n
, demux
[demux_index
].ECMpids
[n
].CAID
,
2605 demux
[demux_index
].ECMpids
[n
].PROVID
, demux
[demux_index
].ECMpids
[n
].ECM_PID
, (uint16_t) prio
->chid
);
2607 return; // go start descrambling since its forced by user!
2611 if(!demux
[demux_index
].ECMpids
[n
].status
) // only accept first matching prio from oscam.dvbapi
2613 demux
[demux_index
].ECMpids
[n
].status
= total_reader
+ p_order
--;
2615 cs_log_dbg(D_DVBAPI
, "Demuxer %d prio%s ecmpid %d %04X@%06X:%04X:%04X weight: %d (file)", demux_index
,
2616 ((prio
->caid
== er
->caid
&& prio
->caid
!= er
->ocaid
) ? " betatunneled" : ""), n
, demux
[demux_index
].ECMpids
[n
].CAID
,
2617 demux
[demux_index
].ECMpids
[n
].PROVID
, demux
[demux_index
].ECMpids
[n
].ECM_PID
, (uint16_t) prio
->chid
, demux
[demux_index
].ECMpids
[n
].status
);
2619 continue; // evaluate next ecmpid
2622 if(prio
->type
== 'i' && prio
->chid
== 0x10000 && demux
[demux_index
].ECMpids
[n
].status
== 0) // check for ignore all chids
2624 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
,
2625 demux
[demux_index
].ECMpids
[n
].PROVID
, demux
[demux_index
].ECMpids
[n
].ECM_PID
);
2626 demux
[demux_index
].ECMpids
[n
].status
= -1;
2627 continue; // evaluate next ecmpid
2632 p_order
= demux
[demux_index
].ECMpidcount
+1;
2634 for(n
= 0; n
< demux
[demux_index
].ECMpidcount
; n
++)
2636 if(demux
[demux_index
].ECMpids
[n
].status
== -1) continue; // skip ignores!
2640 er
->caid
= er
->ocaid
= demux
[demux_index
].ECMpids
[n
].CAID
;
2641 er
->prid
= demux
[demux_index
].ECMpids
[n
].PROVID
;
2642 er
->pid
= demux
[demux_index
].ECMpids
[n
].ECM_PID
;
2643 er
->srvid
= demux
[demux_index
].program_number
;
2644 er
->client
= cur_client();
2645 btun_caid
= chk_on_btun(SRVID_MASK
, er
->client
, er
);
2649 er
->caid
= btun_caid
;
2652 match_reader_count
= 0;
2653 for(rdr
= first_active_reader
; rdr
; rdr
= rdr
->next
)
2655 if(matching_reader(er
, rdr
))
2657 match_reader_count
++;
2661 if(match_reader_count
== 0)
2663 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
,
2664 demux
[demux_index
].ECMpids
[n
].PROVID
, demux
[demux_index
].ECMpids
[n
].ECM_PID
, demux
[demux_index
].ECMpids
[n
].CHID
);
2665 demux
[demux_index
].ECMpids
[n
].status
= -1;
2666 continue; // evaluate next ecmpid
2670 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
2672 if(sidtab
->num_caid
| sidtab
->num_provid
| sidtab
->num_srvid
)
2674 if((cfg
.dvbapi_sidtabs
.no
& ((SIDTABBITS
)1 << nr
)) && (chk_srvid_match(er
, sidtab
)))
2676 demux
[demux_index
].ECMpids
[n
].status
= -1; //ignore
2677 cs_log_dbg(D_DVBAPI
, "Demuxer %d ignore ecmpid %d %04X@%06X:%04X (service %s pos %d)", demux_index
,
2678 n
, demux
[demux_index
].ECMpids
[n
].CAID
, demux
[demux_index
].ECMpids
[n
].PROVID
,
2679 demux
[demux_index
].ECMpids
[n
].ECM_PID
, sidtab
->label
, nr
);
2680 continue; // evaluate next ecmpid
2682 if((cfg
.dvbapi_sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) && (chk_srvid_match(er
, sidtab
)))
2684 demux
[demux_index
].ECMpids
[n
].status
++; //priority
2685 cs_log_dbg(D_DVBAPI
, "Demuxer %d prio ecmpid %d %04X@%06X:%04X weight: %d (service %s pos %d)", demux_index
,
2686 n
, demux
[demux_index
].ECMpids
[n
].CAID
, demux
[demux_index
].ECMpids
[n
].PROVID
,
2687 demux
[demux_index
].ECMpids
[n
].ECM_PID
, demux
[demux_index
].ECMpids
[n
].status
, sidtab
->label
,nr
);
2693 // ecmpids with no matching readers are disabled and matching sidtabbits have now highest status
2696 // ecmpid with highest prio from oscam.dvbapi has now highest status
2698 // check all ecmpids and get the highest amount cache-ex and local readers
2699 int32_t max_local_matching_reader
= 0, max_cacheex_reader
= 0;
2700 for(n
= 0; n
< demux
[demux_index
].ECMpidcount
; n
++)
2702 int32_t count_matching_cacheex_reader
= 0, count_matching_local_reader
= 0;
2704 if(demux
[demux_index
].ECMpids
[n
].status
== -1) continue; // skip ignores!
2706 er
->caid
= er
->ocaid
= demux
[demux_index
].ECMpids
[n
].CAID
;
2707 er
->prid
= demux
[demux_index
].ECMpids
[n
].PROVID
;
2708 er
->pid
= demux
[demux_index
].ECMpids
[n
].ECM_PID
;
2709 er
->srvid
= demux
[demux_index
].program_number
;
2710 er
->client
= cur_client();
2711 btun_caid
= chk_on_btun(SRVID_MASK
, er
->client
, er
);
2715 er
->caid
= btun_caid
;
2718 for(rdr
= first_active_reader
; rdr
; rdr
= rdr
->next
)
2720 if(matching_reader(er
, rdr
))
2722 if(cacheex_reader(rdr
))
2724 count_matching_cacheex_reader
++;
2726 else if(is_localreader(rdr
, er
))
2728 count_matching_local_reader
++;
2733 if(max_local_matching_reader
< count_matching_local_reader
)
2735 max_local_matching_reader
= count_matching_local_reader
;
2737 if(max_cacheex_reader
< count_matching_cacheex_reader
)
2739 max_cacheex_reader
= count_matching_cacheex_reader
;
2743 if(max_local_matching_reader
!= 0 || max_cacheex_reader
!= 0)
2745 p_order
= demux
[demux_index
].ECMpidcount
*2;
2747 for(n
= 0; n
< demux
[demux_index
].ECMpidcount
; n
++)
2749 int32_t count_matching_cacheex_reader
= 0, count_matching_local_reader
= 0;
2750 int32_t localprio
= 1, cacheexprio
= 1;
2752 if(demux
[demux_index
].ECMpids
[n
].status
== -1) continue; // skip ignores!
2754 if(cfg
.preferlocalcards
== 2) // ecmpids with local reader get highest prio
2756 localprio
= max_cacheex_reader
+p_order
+1;
2758 else if(cfg
.preferlocalcards
== 1) // ecmpids with cacheex reader get highest prio
2760 cacheexprio
= max_local_matching_reader
+p_order
+1;
2763 er
->caid
= er
->ocaid
= demux
[demux_index
].ECMpids
[n
].CAID
;
2764 er
->prid
= demux
[demux_index
].ECMpids
[n
].PROVID
;
2765 er
->pid
= demux
[demux_index
].ECMpids
[n
].ECM_PID
;
2766 er
->srvid
= demux
[demux_index
].program_number
;
2767 er
->client
= cur_client();
2768 btun_caid
= chk_on_btun(SRVID_MASK
, er
->client
, er
);
2772 er
->caid
= btun_caid
;
2774 int32_t oldstatus
= demux
[demux_index
].ECMpids
[n
].status
;
2775 int32_t anyreader
= 0;
2776 for(rdr
= first_active_reader
; rdr
; rdr
= rdr
->next
)
2778 if(matching_reader(er
, rdr
))
2780 if(cfg
.preferlocalcards
== 0)
2782 if(!matching_done
) {demux
[demux_index
].ECMpids
[n
].status
++;}
2786 if(cacheex_reader(rdr
))
2788 demux
[demux_index
].ECMpids
[n
].status
+= cacheexprio
;
2789 count_matching_cacheex_reader
++;
2792 if(is_localreader(rdr
, er
))
2794 demux
[demux_index
].ECMpids
[n
].status
+= localprio
;
2795 count_matching_local_reader
++;
2801 if(oldstatus
!= demux
[demux_index
].ECMpids
[n
].status
)
2805 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
,
2806 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
);
2810 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
,
2811 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
,
2812 count_matching_local_reader
, count_matching_cacheex_reader
);
2818 struct s_channel_cache
*c
= NULL
;
2820 for(n
= 0; n
< demux
[demux_index
].ECMpidcount
&& matching_done
== 0; n
++)
2822 if(demux
[demux_index
].ECMpids
[n
].status
== -1) continue; // skip ignores!
2824 c
= dvbapi_find_channel_cache(demux_index
, n
, 0); // find exact channel match
2828 cache
= 2; //found cache entry with higher priority
2829 demux
[demux_index
].ECMpids
[n
].status
++; // prioritize CAIDs which already decoded same caid:provid:srvid
2830 if(c
->chid
< 0x10000) { demux
[demux_index
].ECMpids
[n
].CHID
= c
->chid
; } // if chid registered in cache -> use it!
2831 cs_log_dbg(D_DVBAPI
, "Demuxer %d prio ecmpid %d %04X@%06X:%04X weight: %d (found caid/provid/srvid in cache)", demux_index
, n
,
2832 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
);
2839 // prioritize CAIDs which already decoded same caid:provid
2840 for(n
= 0; n
< demux
[demux_index
].ECMpidcount
&& matching_done
== 0; n
++)
2842 if(demux
[demux_index
].ECMpids
[n
].status
== -1) continue; // skip ignores!
2844 c
= dvbapi_find_channel_cache(demux_index
, n
, 1);
2847 cache
= 1; //found cache entry
2848 demux
[demux_index
].ECMpids
[n
].status
++;
2849 cs_log_dbg(D_DVBAPI
, "Demuxer %d prio ecmpid %d %04X@%06X:%04X weight: %d (found caid/provid in cache)", demux_index
, n
,
2850 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
);
2855 int32_t max_status
= 0;
2856 int32_t highest_priopid
= -1;
2858 for(n
= 0; n
< demux
[demux_index
].ECMpidcount
; n
++)
2860 if(demux
[demux_index
].ECMpids
[n
].status
== -1) continue; // skip ignores!
2862 if(demux
[demux_index
].ECMpids
[n
].status
> max_status
) // find highest prio pid
2864 max_status
= demux
[demux_index
].ECMpids
[n
].status
;
2865 highest_priopid
= n
;
2867 if(!USE_OPENXCAS
) // openxcas doesnt use prio and non-prio run: all are equal!
2869 if(demux
[demux_index
].ECMpids
[n
].status
== 0) { demux
[demux_index
].ECMpids
[n
].checked
= 2; } // set pids with no status to no prio run
2873 demux
[demux_index
].max_status
= max_status
; // register maxstatus
2874 if(highest_priopid
!= -1 && found
== highest_priopid
&& cache
== 2) // Found entry in channelcache that is valid and has exact match on srvid
2876 for(n
= 0; n
< demux
[demux_index
].ECMpidcount
; n
++)
2878 if(demux
[demux_index
].ECMpids
[n
].status
== -1) continue; // skip ignores!
2882 // disable non matching pid
2883 demux
[demux_index
].ECMpids
[n
].status
= -1;
2887 demux
[demux_index
].ECMpids
[n
].status
= 1;
2890 demux
[demux_index
].max_emm_filter
= maxfilter
- 1;
2891 demux
[demux_index
].max_status
= 1;
2892 cs_log("Demuxer %d found channel in cache and matching prio -> start descrambling ecmpid %d ", demux_index
, found
);
2898 int64_t gone
= comp_timeb(&end
, &start
);
2899 cs_log_dbg(D_DVBAPI
, "Demuxer %d sorting the ecmpids took %"PRId64
" ms", demux_index
, gone
);
2903 void dvbapi_parse_descriptor(int32_t demux_id
, uint32_t info_length
, unsigned char *buffer
, uint8_t* is_audio
)
2905 // int32_t ca_pmt_cmd_id = buffer[i + 5];
2906 uint32_t descriptor_length
= 0;
2908 uint8_t skip_border
= cfg
.dvbapi_boxtype
== BOXTYPE_SAMYGO
? 0x05 : 0x02; // skip input values <0x05 on samygo
2910 static const char format_identifiers_audio
[10][5] =
2912 "AC-3", "BSSD", "dmat", "DTS1", "DTS2",
2913 "DTS3", "EAC3", "HDMV", "mlpa", "Opus",
2919 if((buffer
[0] < skip_border
) && info_length
> 0) // skip input values like 0x00 and 0x01
2925 for(j
= 0; j
+ 1 < info_length
; j
+= descriptor_length
+ 2)
2927 descriptor_length
= buffer
[j
+ 1];
2931 if(buffer
[j
] == 0x6A || buffer
[j
] == 0x73 || buffer
[j
] == 0x81)
2935 else if(buffer
[j
] == 0x05 && descriptor_length
>= 4)
2937 for(k
= 0; k
< 10; k
++)
2939 if(memcmp(buffer
+ j
+ 2, format_identifiers_audio
[k
], 4) == 0)
2948 if(buffer
[j
] == 0x81 && descriptor_length
== 8) // private descriptor of length 8, assume enigma/tvh
2950 demux
[demux_id
].enigma_namespace
= b2i(4, buffer
+ j
+ 2);
2951 demux
[demux_id
].tsid
= b2i(2, buffer
+ j
+ 6);
2952 demux
[demux_id
].onid
= b2i(2, buffer
+ j
+ 8);
2953 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
,
2954 buffer
[j
], descriptor_length
, demux
[demux_id
].enigma_namespace
, demux
[demux_id
].tsid
, demux
[demux_id
].onid
);
2956 else if (descriptor_length
!=0)
2958 cs_log_dbg(D_TRACE
, "Demuxer %d found pmt type: %02x length: %d", demux_id
, buffer
[j
], descriptor_length
);
2961 if(buffer
[j
] != 0x09) { continue; }
2963 int32_t descriptor_ca_system_id
= b2i(2, buffer
+ j
+ 2);
2964 int32_t descriptor_ca_pid
= b2i(2, buffer
+ j
+ 4)&0x1FFF;
2965 int32_t descriptor_ca_provider
= 0;
2966 uint32_t descriptor_ca_data
= 0;
2967 char txt
[40]; // room for PBM: 8 byte pbm and DATE: date
2968 memset(txt
, 0x00, sizeof(txt
));
2970 if(descriptor_ca_system_id
>> 8 == 0x01)
2972 for(u
= 2; u
< descriptor_length
; u
+= 15)
2974 descriptor_ca_pid
= b2i(2, buffer
+ j
+ u
+ 2)&0x1FFF;
2975 descriptor_ca_provider
= b2i(2, buffer
+ j
+ u
+ 4);
2976 int8_t year
= buffer
[j
+ u
+ 15] >> 1;
2977 int8_t month
= (((buffer
[j
+ u
+ 15]&0x01) << 3) | (buffer
[j
+ u
+ 16] >> 5));
2978 int8_t day
= buffer
[j
+ u
+ 16]&0x1F;
2979 snprintf(txt
, sizeof(txt
), "PBM: ");
2980 cs_hexdump(0, buffer
+ j
+ u
+ 7, 8, txt
+5, (2*8)+1); // hexdump 8 byte pbm
2981 snprintf(txt
+20, sizeof(txt
)-20, " DATE: %d-%d-%d", day
, month
, year
+1990);
2982 dvbapi_add_ecmpid(demux_id
, descriptor_ca_system_id
, descriptor_ca_pid
, descriptor_ca_provider
, 0, txt
);
2987 if(caid_is_viaccess(descriptor_ca_system_id
) && descriptor_length
== 0x0F && buffer
[j
+ 12] == 0x14)
2988 { descriptor_ca_provider
= b2i(3, buffer
+ j
+ 14) &0xFFFFF0; }
2990 else if(caid_is_nagra(descriptor_ca_system_id
) && descriptor_length
== 0x07)
2991 { descriptor_ca_provider
= b2i(2, buffer
+ j
+ 7); }
2993 else if((descriptor_ca_system_id
>> 8 == 0x4A || descriptor_ca_system_id
== 0x2710) && descriptor_length
> 0x04 )
2995 descriptor_ca_provider
= buffer
[j
+ 6];
2997 if(caid_is_dre(descriptor_ca_system_id
) && descriptor_length
== 0xA)
2999 descriptor_ca_data
= (buffer
[j
+8] << 24) | (buffer
[j
+9] << 16) | (buffer
[j
+10] << 8) | buffer
[j
+11];
3000 snprintf(txt
, 40, "CA DATA: %X", descriptor_ca_data
);
3004 dvbapi_add_ecmpid(demux_id
, descriptor_ca_system_id
, descriptor_ca_pid
, descriptor_ca_provider
, descriptor_ca_data
, txt
);
3012 struct s_dvbapi_priority
*mapentry
;
3013 for(j
= 0; (int32_t)j
< demux
[demux_id
].ECMpidcount
; j
++)
3015 mapentry
= dvbapi_check_prio_match(demux_id
, j
, 'm');
3018 cs_log_dbg(D_DVBAPI
, "Demuxer %d mapping ecmpid %d from %04X@%06X to %04X@%06X", demux_id
, j
,
3019 demux
[demux_id
].ECMpids
[j
].CAID
, demux
[demux_id
].ECMpids
[j
].PROVID
,
3020 mapentry
->mapcaid
, mapentry
->mapprovid
);
3021 demux
[demux_id
].ECMpids
[j
].CAID
= mapentry
->mapcaid
;
3022 demux
[demux_id
].ECMpids
[j
].PROVID
= mapentry
->mapprovid
;
3028 void request_cw(struct s_client
*client
, ECM_REQUEST
*er
, int32_t demux_id
, uint8_t delayed_ecm_check
)
3036 int32_t filternum
= dvbapi_set_section_filter(demux_id
, er
, -1); // set ecm filter to odd -> even and visaversa
3039 cs_log_dbg(D_DVBAPI
, "Demuxer %d not requesting cw -> ecm filter was killed!", demux_id
);
3044 if(!delayed_ecm_check
) // no delayed ecm check for this filter
3046 memset(demux
[demux_id
].demux_fd
[filternum
].lastecmd5
, 0, CS_ECMSTORESIZE
); // no ecm delay check: zero it!
3050 unsigned char md5tmp
[MD5_DIGEST_LENGTH
];
3051 MD5(er
->ecm
, er
->ecmlen
, md5tmp
);
3052 if(!memcmp(demux
[demux_id
].demux_fd
[filternum
].prevecmd5
, md5tmp
, CS_ECMSTORESIZE
))
3054 if(demux
[demux_id
].demux_fd
[filternum
].prevresult
< E_NOTFOUND
)
3056 cs_log_dbg(D_DVBAPI
, "Demuxer %d not requesting same ecm again! -> SKIP!", demux_id
);
3062 cs_log_dbg(D_DVBAPI
, "Demuxer %d requesting same ecm again (previous result was not found!)", demux_id
);
3065 else if(!memcmp(demux
[demux_id
].demux_fd
[filternum
].lastecmd5
, md5tmp
, CS_ECMSTORESIZE
))
3067 if(demux
[demux_id
].demux_fd
[filternum
].lastresult
< E_NOTFOUND
)
3069 cs_log_dbg(D_DVBAPI
, "Demuxer %d not requesting same ecm again! -> SKIP!", demux_id
);
3075 cs_log_dbg(D_DVBAPI
, "Demuxer %d requesting same ecm again (previous result was not found!)", demux_id
);
3078 memcpy(demux
[demux_id
].demux_fd
[filternum
].prevecmd5
, demux
[demux_id
].demux_fd
[filternum
].lastecmd5
, CS_ECMSTORESIZE
);
3079 demux
[demux_id
].demux_fd
[filternum
].prevresult
= demux
[demux_id
].demux_fd
[filternum
].lastresult
;
3080 memcpy(demux
[demux_id
].demux_fd
[filternum
].lastecmd5
, md5tmp
, CS_ECMSTORESIZE
);
3081 demux
[demux_id
].demux_fd
[filternum
].lastresult
= 0xFF;
3084 er
->adapter_index
= demux
[demux_id
].adapter_index
;
3086 cs_log_dbg(D_DVBAPI
, "Demuxer %d get controlword!", demux_id
);
3090 char buf
[ECM_FMT_LEN
];
3091 format_ecm(er
, buf
, ECM_FMT_LEN
);
3092 cs_log_dbg(D_DVBAPI
, "Demuxer %d request controlword for ecm %s", demux_id
, buf
);
3096 void dvbapi_try_next_caid(int32_t demux_id
, int8_t checked
, uint32_t msgid
)
3099 int32_t n
, j
, found
= -1, started
= 0;
3101 int32_t status
= demux
[demux_id
].max_status
;
3103 for(j
= status
; j
>= 0; j
--) // largest status first!
3106 for(n
= 0; n
< demux
[demux_id
].ECMpidcount
; n
++)
3108 //cs_log_dbg(D_DVBAPI,"Demuxer %d PID %d checked = %d status = %d (searching for pid with status = %d)", demux_id, n,
3109 // demux[demux_id].ECMpids[n].checked, demux[demux_id].ECMpids[n].status, j);
3110 if(demux
[demux_id
].ECMpids
[n
].checked
== checked
&& demux
[demux_id
].ECMpids
[n
].status
== j
)
3114 openxcas_set_provid(demux
[demux_id
].ECMpids
[found
].PROVID
);
3115 openxcas_set_caid(demux
[demux_id
].ECMpids
[found
].CAID
);
3116 openxcas_set_ecm_pid(demux
[demux_id
].ECMpids
[found
].ECM_PID
);
3118 // fixup for cas that need emm first!
3119 if(caid_is_irdeto(demux
[demux_id
].ECMpids
[found
].CAID
)
3120 || (caid_is_dre(demux
[demux_id
].ECMpids
[found
].CAID
) && ((demux
[demux_id
].ECMpids
[found
].PROVID
== 0x11 || demux
[demux_id
].ECMpids
[found
].PROVID
== 0xFE))))
3121 { demux
[demux_id
].emmstart
.time
= 0; }
3122 started
= dvbapi_start_descrambling(demux_id
, found
, checked
, msgid
);
3123 if(cfg
.dvbapi_requestmode
== 0 && started
== 1) { return; } // in requestmode 0 we only start 1 ecm request at the time
3128 if(found
== -1 && demux
[demux_id
].pidindex
== -1)
3130 cs_log("Demuxer %d no suitable readers found that can be used for decoding!", demux_id
);
3135 static void getDemuxOptions(int32_t demux_id
, unsigned char *buffer
, uint32_t *ca_mask
, uint16_t *demux_index
, uint16_t *adapter_index
, uint16_t *pmtpid
)
3137 *ca_mask
= 0x01, *demux_index
= 0x00, *adapter_index
= 0x00, *pmtpid
= 0x00;
3139 if(buffer
[17] == 0x82 && buffer
[18] == 0x02)
3142 *ca_mask
= buffer
[19];
3143 uint32_t demuxid
= buffer
[20];
3144 if (demuxid
== 0xff) demuxid
= 0; // tryfix prismcube (0xff -> "demux-1" = error! )
3145 *demux_index
= demuxid
;
3146 if (buffer
[21]==0x84 && buffer
[22]==0x02) *pmtpid
= b2i(2, buffer
+23);
3147 if (buffer
[25]==0x83 && buffer
[26]==0x01) *adapter_index
=buffer
[27]; // from code cahandler.cpp 0x83 index of adapter
3150 if(cfg
.dvbapi_boxtype
== BOXTYPE_IPBOX_PMT
)
3152 *ca_mask
= demux_id
+ 1;
3153 *demux_index
= demux_id
;
3156 if(cfg
.dvbapi_boxtype
== BOXTYPE_QBOXHD
&& buffer
[17] == 0x82 && buffer
[18] == 0x03)
3158 // ca_mask = buffer[19]; // with STONE 1.0.4 always 0x01
3159 *demux_index
= buffer
[20]; // with STONE 1.0.4 always 0x00
3160 *adapter_index
= buffer
[21]; // with STONE 1.0.4 adapter index can be 0,1,2
3161 *ca_mask
= (1 << *adapter_index
); // use adapter_index as ca_mask (used as index for ca_fd[] array)
3164 if((cfg
.dvbapi_boxtype
== BOXTYPE_PC
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
|| cfg
.dvbapi_boxtype
== BOXTYPE_SAMYGO
)
3165 && buffer
[7] == 0x82 && buffer
[8] == 0x02)
3167 *demux_index
= buffer
[9]; // it is always 0 but you never know
3168 *adapter_index
= buffer
[10]; // adapter index can be 0,1,2
3169 *ca_mask
= (1 << *adapter_index
); // use adapter_index as ca_mask (used as index for ca_fd[] array)
3170 if (buffer
[21]==0x84 && buffer
[22]==0x02) *pmtpid
= b2i(2, buffer
+23);
3174 static void dvbapi_capmt_notify(struct demux_s
*dmx
)
3176 struct s_client
*cl
;
3177 for(cl
= first_client
->next
; cl
; cl
= cl
->next
)
3179 if((cl
->typ
== 'p' || cl
->typ
== 'r') && cl
->reader
&& cl
->reader
->ph
.c_capmt
)
3181 struct demux_s
*curdemux
;
3182 if(cs_malloc(&curdemux
, sizeof(struct demux_s
)))
3184 memcpy(curdemux
, dmx
, sizeof(struct demux_s
));
3185 add_job(cl
, ACTION_READER_CAPMT_NOTIFY
, curdemux
, sizeof(struct demux_s
));
3191 int32_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
, uint32_t msgid
)
3193 uint32_t i
= 0, start_descrambling
= 0;
3195 int32_t demux_id
= -1;
3196 uint16_t demux_index
, adapter_index
, pmtpid
;
3198 uint32_t program_number
, program_info_length
;
3199 uint8_t program_info_start
= is_real_pmt
? 12 : 6;
3204 #define LIST_MORE 0x00 //*CA application should append a 'MORE' CAPMT object to the list and start receiving the next object
3205 #define LIST_FIRST 0x01 //*CA application should clear the list when a 'FIRST' CAPMT object is received, and start receiving the next object
3206 #define LIST_LAST 0x02 //*CA application should append a 'LAST' CAPMT object to the list and start working with the list
3207 #define LIST_ONLY 0x03 //*CA application should clear the list when an 'ONLY' CAPMT object is received, and start working with the object
3208 #define LIST_ADD 0x04 //*CA application should append an 'ADD' CAPMT object to the current list and start working with the updated list
3209 #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
3211 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
3212 int32_t ca_pmt_list_management
= LIST_ONLY
;
3214 int32_t ca_pmt_list_management
= buffer
[0];
3216 program_number
= b2i(2, buffer
+ 1);
3217 program_info_length
= b2i(2, buffer
+ 4) &0xFFF;
3219 cs_log_dump_dbg(D_DVBAPI
, buffer
, length
, "capmt:");
3220 cs_log_dbg(D_DVBAPI
, "Receiver sends PMT command %d for channel %04X", ca_pmt_list_management
, program_number
);
3222 if(!pmt_stopmarking
&& (ca_pmt_list_management
== LIST_FIRST
|| ca_pmt_list_management
== LIST_ONLY
))
3224 for(i
= 0; i
< MAX_DEMUX
; i
++)
3226 if(demux
[i
].program_number
== 0) { continue; } // skip empty demuxers
3227 if(demux
[i
].socket_fd
!= connfd
) { continue; } // skip demuxers belonging to other ca pmt connection
3228 if((demux
[i
].socket_fd
== -1) && (pmtfile
&& strcmp(demux
[i
].pmt_file
, pmtfile
) != 0)) { continue; } // skip demuxers handled by other pmt files
3229 demux
[i
].stopdescramble
= 1; // Mark for deletion if not used again by following pmt objects.
3230 cs_log_dbg(D_DVBAPI
, "Marked demuxer %d/%d (srvid = %04X fd = %d) to stop decoding", i
, MAX_DEMUX
, demux
[i
].program_number
, connfd
);
3232 pmt_stopmarking
= 1; // only stop demuxing for first pmt record
3235 getDemuxOptions(i
, buffer
, &ca_mask
, &demux_index
, &adapter_index
, &pmtpid
);
3236 cs_log_dbg(D_DVBAPI
,"Receiver wants to demux srvid %04X on adapter %04X camask %04X index %04X pmtpid %04X",
3237 program_number
, adapter_index
, ca_mask
, demux_index
, pmtpid
);
3239 for(i
= 0; i
< MAX_DEMUX
; i
++) // search current demuxers for running the same program as the one we received in this PMT object
3241 if(demux
[i
].program_number
== 0) { continue; }
3242 if(cfg
.dvbapi_boxtype
== BOXTYPE_IPBOX_PMT
) demux_index
= i
; // fixup for ipbox
3244 bool full_check
= 1, matched
= 0;
3245 if (config_enabled(WITH_COOLAPI
) || config_enabled(WITH_COOLAPI2
) || cfg
.dvbapi_boxtype
== BOXTYPE_SAMYGO
)
3249 matched
= (connfd
> 0 && demux
[i
].socket_fd
== connfd
) && demux
[i
].program_number
== program_number
;
3251 matched
= connfd
> 0 && demux
[i
].program_number
== program_number
;
3256 if (demux
[i
].adapter_index
!= adapter_index
) continue; // perhaps next demuxer matches?
3257 if (demux
[i
].ca_mask
!= ca_mask
) continue; // perhaps next demuxer matches?
3258 if (demux
[i
].demux_index
!= demux_index
) continue; // perhaps next demuxer matches?
3260 if(ca_pmt_list_management
== LIST_UPDATE
){
3261 cs_log("Demuxer %d PMT update for decoding of SRVID %04X! ", i
, program_number
);
3266 cs_log("Demuxer %d continue decoding of SRVID %04X", i
, demux
[i
].program_number
);
3268 openxcas_set_sid(program_number
);
3270 demux
[i
].stopdescramble
= 0; // dont stop current demuxer!
3271 break; // no need to explore other demuxers since we have a found!
3275 // start using the new list
3276 if(ca_pmt_list_management
!= LIST_FIRST
&& ca_pmt_list_management
!= LIST_MORE
)
3278 for(j
= 0; j
< MAX_DEMUX
; j
++)
3280 if(demux
[j
].program_number
== 0) { continue; }
3281 if(demux
[j
].stopdescramble
== 1) { dvbapi_stop_descrambling(j
, msgid
); }// Stop descrambling and remove all demuxer entries not in new PMT.
3283 start_descrambling
= 1; // flag that demuxer descrambling is to be executed!
3284 pmt_stopmarking
= 0; // flag that demuxers may be marked for stop decoding again
3289 for(demux_id
= 0; demux_id
< MAX_DEMUX
; demux_id
++)
3291 if(demux
[demux_id
].program_number
== 0)
3293 demux
[demux_id
].program_number
= program_number
; // do this early since some prio items use them!
3294 demux
[demux_id
].enigma_namespace
= 0;
3295 demux
[demux_id
].tsid
= 0;
3296 demux
[demux_id
].onid
= 0;
3297 demux
[demux_id
].pmtpid
= pmtpid
;
3298 demux
[demux_id
].socket_fd
= connfd
;
3299 demux
[demux_id
].adapter_index
= adapter_index
;
3300 demux
[demux_id
].client_proto_version
= client_proto_version
;
3301 demux
[demux_id
].sdt_filter
= -1;
3305 cs_strncpy(demux
[demux_id
].pmt_file
, pmtfile
, sizeof(demux
[demux_id
].pmt_file
));
3308 // free demuxer found, start pat/pmt filter for this new demuxer
3311 dvbapi_start_pmt_filter(demux_id
, pmtpid
);
3315 dvbapi_start_pat_filter(demux_id
);
3322 if(demux_id
>= MAX_DEMUX
)
3324 cs_log("ERROR: No free id (MAX_DEMUX)");
3328 if(demux
[demux_id
].running
== 0) demux
[demux_id
].ECMpidcount
= 0; // reset number of ecmpids only if it was not running!
3332 demux_id
= existing_demux_id
;
3334 dvbapi_stop_filter(demux_id
, TYPE_PMT
, msgid
);
3336 program_number
= b2i(2, buffer
+ 3);
3337 program_info_length
= b2i(2, buffer
+ 10) &0xFFF;
3339 cs_log_dump_dbg(D_DVBAPI
, buffer
, length
, "pmt:");
3340 pmtpid
= demux
[demux_id
].pmtpid
;
3343 for(j
= 0; j
< demux
[demux_id
].ECMpidcount
; j
++) // cleanout demuxer from possible stale info
3345 demux
[demux_id
].ECMpids
[j
].streams
= 0; // reset streams of each ecmpid!
3347 demux
[demux_id
].STREAMpidcount
= 0; // reset number of streams
3349 if(program_info_length
> 1 && program_info_length
< length
)
3351 dvbapi_parse_descriptor(demux_id
, program_info_length
, buffer
+ program_info_start
, NULL
);
3354 uint32_t es_info_length
= 0, vpid
= 0;
3355 struct s_dvbapi_priority
*addentry
;
3357 for(i
= program_info_length
+ program_info_start
; i
+ 4 < length
; i
+= es_info_length
+ 5)
3359 uint8_t stream_type
= buffer
[i
];
3360 uint16_t elementary_pid
= b2i(2, buffer
+ i
+ 1)&0x1FFF;
3361 uint8_t is_audio
= 0;
3362 es_info_length
= b2i(2, buffer
+ i
+3)&0x0FFF;
3364 if(demux
[demux_id
].STREAMpidcount
< ECM_PIDS
)
3367 demux
[demux_id
].STREAMpids
[demux
[demux_id
].STREAMpidcount
] = elementary_pid
;
3368 demux
[demux_id
].STREAMpidsType
[demux
[demux_id
].STREAMpidcount
] = buffer
[i
];
3369 demux
[demux_id
].STREAMpidcount
++;
3371 cs_log_dbg(D_DVBAPI
,"Demuxer %d stream %s(type: %02x pid: %04x length: %d)", demux_id
, get_streamtxt(stream_type
), stream_type
, elementary_pid
,
3374 // find and register videopid
3376 (stream_type
== 0x01 || stream_type
== 0x02 || stream_type
== 0x10 || stream_type
== 0x1B
3377 || stream_type
== 0x24 || stream_type
== 0x42 || stream_type
== 0xD1 || stream_type
== 0xEA))
3379 vpid
= elementary_pid
;
3382 if(es_info_length
!= 0 && es_info_length
< length
)
3384 dvbapi_parse_descriptor(demux_id
, es_info_length
, buffer
+ i
+ 5, &is_audio
);
3386 if((stream_type
== 0x06 || stream_type
== 0x80 || stream_type
== 0x82) && is_audio
)
3388 demux
[demux_id
].STREAMpidsType
[demux
[demux_id
].STREAMpidcount
-1] = 0x03;
3391 else if(!vpid
&& stream_type
== 0x80 && !is_audio
)
3393 vpid
= elementary_pid
;
3398 for(addentry
= dvbapi_priority
; addentry
!= NULL
; addentry
= addentry
->next
)
3400 if(addentry
->type
!= 'a'
3401 || (addentry
->ecmpid
&& pmtpid
&& addentry
->ecmpid
!= pmtpid
) // ecmpid is misused to hold pmtpid in case of A: rule
3402 || (addentry
->ecmpid
&& !pmtpid
&& addentry
->ecmpid
!= vpid
) // some receivers dont forward pmtpid, use vpid instead
3403 || (addentry
->srvid
!= demux
[demux_id
].program_number
))
3405 cs_log_dbg(D_DVBAPI
, "Demuxer %d fake ecmpid %04X@%06X:%04x for unencrypted stream on srvid %04X", demux_id
, addentry
->mapcaid
,
3406 addentry
->mapprovid
, addentry
->mapecmpid
, demux
[demux_id
].program_number
);
3407 dvbapi_add_ecmpid(demux_id
, addentry
->mapcaid
, addentry
->mapecmpid
, addentry
->mapprovid
, 0, " (fake ecmpid)");
3416 cs_log("Demuxer %d found %d ECMpids and %d STREAMpids in caPMT", demux_id
, demux
[demux_id
].ECMpidcount
, demux
[demux_id
].STREAMpidcount
);
3418 getDemuxOptions(demux_id
, buffer
, &ca_mask
, &demux_index
, &adapter_index
, &pmtpid
);
3419 demux
[demux_id
].adapter_index
= adapter_index
;
3420 demux
[demux_id
].ca_mask
= ca_mask
;
3421 demux
[demux_id
].rdr
= NULL
;
3422 demux
[demux_id
].demux_index
= demux_index
;
3423 demux
[demux_id
].socket_fd
= connfd
;
3424 demux
[demux_id
].client_proto_version
= client_proto_version
;
3426 if(demux
[demux_id
].STREAMpidcount
== 0) // encrypted PMT
3428 demux
[demux_id
].STREAMpids
[demux
[demux_id
].STREAMpidcount
] = pmtpid
;
3429 demux
[demux_id
].STREAMpidsType
[demux
[demux_id
].STREAMpidcount
] = 0x01;
3430 demux
[demux_id
].STREAMpidcount
++;
3436 cs_log("Demuxer %d found %d ECMpids and %d STREAMpids in PMT", demux_id
, demux
[demux_id
].ECMpidcount
, demux
[demux_id
].STREAMpidcount
);
3438 ca_mask
= demux
[demux_id
].ca_mask
;
3439 demux_index
= demux
[demux_id
].demux_index
;
3440 adapter_index
= demux
[demux_id
].adapter_index
;
3441 connfd
= demux
[demux_id
].socket_fd
;
3444 for(j
= 0; j
< demux
[demux_id
].ECMpidcount
; j
++)
3446 demux
[demux_id
].ECMpids
[j
].VPID
= vpid
; // register found vpid on all ecmpids of this demuxer
3449 char channame
[CS_SERVICENAME_SIZE
];
3450 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
));
3451 cs_log_dbg(D_DVBAPI
,"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
);
3452 demux
[demux_id
].stopdescramble
= 0; // remove deletion mark!
3454 // remove from unassoc_fd when necessary
3455 for (j
= 0; j
< MAX_DEMUX
; j
++)
3456 if (unassoc_fd
[j
] == connfd
)
3459 dvbapi_capmt_notify(&demux
[demux_id
]);
3461 struct s_dvbapi_priority
*xtraentry
;
3462 int32_t k
, l
, m
, xtra_demux_id
;
3464 for(xtraentry
= dvbapi_priority
; xtraentry
!= NULL
; xtraentry
= xtraentry
->next
)
3466 if(xtraentry
->type
!= 'x') { continue; }
3468 for(j
= 0; j
<= demux
[demux_id
].ECMpidcount
; ++j
)
3470 if((xtraentry
->caid
&& xtraentry
->caid
!= demux
[demux_id
].ECMpids
[j
].CAID
)
3471 || (xtraentry
->provid
&& xtraentry
->provid
!= demux
[demux_id
].ECMpids
[j
].PROVID
)
3472 || (xtraentry
->ecmpid
&& xtraentry
->ecmpid
!= demux
[demux_id
].ECMpids
[j
].ECM_PID
)
3473 || (xtraentry
->srvid
&& xtraentry
->srvid
!= demux
[demux_id
].program_number
))
3476 cs_log("Mapping ecmpid %04X@%06X:%04X:%04X to xtra demuxer/ca-devices", xtraentry
->caid
, xtraentry
->provid
, xtraentry
->ecmpid
, xtraentry
->srvid
);
3478 for(xtra_demux_id
= 0; xtra_demux_id
< MAX_DEMUX
&& demux
[xtra_demux_id
].program_number
> 0; xtra_demux_id
++)
3481 if(xtra_demux_id
>= MAX_DEMUX
)
3483 cs_log("Found no free demux device for xtra streams.");
3486 // copy to new demuxer
3489 getDemuxOptions(demux_id
, buffer
, &ca_mask
, &demux_index
, &adapter_index
, &pmtpid
);
3491 demux
[xtra_demux_id
].ECMpids
[0] = demux
[demux_id
].ECMpids
[j
];
3492 demux
[xtra_demux_id
].ECMpidcount
= 1;
3493 demux
[xtra_demux_id
].STREAMpidcount
= 0;
3494 demux
[xtra_demux_id
].program_number
= demux
[demux_id
].program_number
;
3495 demux
[xtra_demux_id
].pmtpid
= demux
[demux_id
].pmtpid
;
3496 demux
[xtra_demux_id
].demux_index
= demux_index
;
3497 demux
[xtra_demux_id
].adapter_index
= adapter_index
;
3498 demux
[xtra_demux_id
].ca_mask
= ca_mask
;
3499 demux
[xtra_demux_id
].socket_fd
= connfd
;
3500 demux
[xtra_demux_id
].stopdescramble
= 0; // remove deletion mark!
3501 demux
[xtra_demux_id
].rdr
= NULL
;
3502 demux
[xtra_demux_id
].curindex
= -1;
3504 // add streams to xtra demux
3505 for(k
= 0; k
< demux
[demux_id
].STREAMpidcount
; ++k
)
3507 if(!demux
[demux_id
].ECMpids
[j
].streams
|| (demux
[demux_id
].ECMpids
[j
].streams
& (1 << k
)))
3509 demux
[xtra_demux_id
].ECMpids
[0].streams
|= (1 << demux
[xtra_demux_id
].STREAMpidcount
);
3510 demux
[xtra_demux_id
].STREAMpids
[demux
[xtra_demux_id
].STREAMpidcount
] = demux
[demux_id
].STREAMpids
[k
];
3511 demux
[xtra_demux_id
].STREAMpidsType
[demux
[xtra_demux_id
].STREAMpidcount
] = demux
[demux_id
].STREAMpidsType
[k
];
3512 ++demux
[xtra_demux_id
].STREAMpidcount
;
3514 // shift stream associations in normal demux because we will remove the stream entirely
3515 for(l
= 0; l
< demux
[demux_id
].ECMpidcount
; ++l
)
3517 for(m
= k
; m
< demux
[demux_id
].STREAMpidcount
- 1; ++m
)
3519 if(demux
[demux_id
].ECMpids
[l
].streams
& (1 << (m
+ 1)))
3521 demux
[demux_id
].ECMpids
[l
].streams
|= (1 << m
);
3525 demux
[demux_id
].ECMpids
[l
].streams
&= ~(1 << m
);
3530 // remove stream association from normal demux device
3531 for(l
= k
; l
< demux
[demux_id
].STREAMpidcount
- 1; ++l
)
3533 demux
[demux_id
].STREAMpids
[l
] = demux
[demux_id
].STREAMpids
[l
+ 1];
3534 demux
[demux_id
].STREAMpidsType
[l
] = demux
[demux_id
].STREAMpidsType
[l
+ 1];
3536 --demux
[demux_id
].STREAMpidcount
;
3541 // remove ecmpid from normal demuxer
3542 for(k
= j
; k
< demux
[demux_id
].ECMpidcount
; ++k
)
3544 demux
[demux_id
].ECMpids
[k
] = demux
[demux_id
].ECMpids
[k
+ 1];
3546 --demux
[demux_id
].ECMpidcount
;
3549 if(demux
[xtra_demux_id
].STREAMpidcount
<= 0)
3551 cs_log("Found no streams for xtra demuxer. Not starting additional decoding on it.");
3552 demux
[xtra_demux_id
].program_number
= 0;
3553 demux
[xtra_demux_id
].stopdescramble
= 1;
3556 if(demux
[demux_id
].STREAMpidcount
< 1)
3558 cs_log("Found no streams for normal demuxer. Not starting additional decoding on it.");
3563 if(start_descrambling
)
3565 for(j
= 0; j
< MAX_DEMUX
; j
++)
3567 if(demux
[j
].program_number
== 0) { continue; }
3568 if(demux
[j
].socket_fd
!= connfd
) { continue; } // skip demuxers belonging to other ca pmt connection
3569 if((demux
[j
].socket_fd
== -1) && (pmtfile
&& strcmp(demux
[j
].pmt_file
, pmtfile
) != 0)) { continue; } // skip demuxers handled by other pmt files
3571 if(demux
[j
].running
&& demux_id
== j
) disable_unused_streampids(j
); // disable all streampids not in use anymore
3573 if(demux
[j
].running
== 0 && demux
[j
].ECMpidcount
!= 0 ) // only start demuxer if it wasnt running
3575 dvbapi_stop_all_emm_sdt_filtering(msgid
); // remove all unimportant filtering (there are images with limited amount of filters available!)
3576 cs_log_dbg(D_DVBAPI
, "Demuxer %d/%d lets start descrambling (srvid = %04X fd = %d ecmpids = %d)", j
, MAX_DEMUX
,
3577 demux
[j
].program_number
, connfd
, demux
[j
].ECMpidcount
);
3578 demux
[j
].running
= 1; // mark channel as running
3579 openxcas_set_sid(demux
[j
].program_number
);
3580 demux
[j
].decodingtries
= -1;
3581 dvbapi_resort_ecmpids(j
);
3582 dvbapi_try_next_caid(j
, 0, msgid
);
3585 else if(demux
[j
].ECMpidcount
== 0) //fta do logging and part of ecmhandler since there will be no ecms asked!
3587 cs_log_dbg(D_DVBAPI
, "Demuxer %d/%d no descrambling needed (srvid = %04X fd = %d ecmpids = %d)", j
, MAX_DEMUX
,
3588 demux
[j
].program_number
, connfd
, demux
[j
].ECMpidcount
);
3589 demux
[j
].running
= 0; // reset running flag
3590 demux
[demux_id
].pidindex
= -1; // reset ecmpid used for descrambling
3591 dvbapi_stop_filter(j
, TYPE_ECM
, msgid
);
3592 if(cfg
.usrfileflag
) { cs_statistics(dvbapi_client
);} // add to user log previous channel + time on channel
3593 dvbapi_client
->last_srvid
= demux
[demux_id
].program_number
; // set new channel srvid
3594 dvbapi_client
->last_caid
= NO_CAID_VALUE
; // FTA channels have no caid!
3595 dvbapi_client
->last_provid
= NO_PROVID_VALUE
; // FTA channels have no provid!
3596 dvbapi_client
->lastswitch
= dvbapi_client
->last
= time((time_t *)0); // reset idle-Time & last switch
3601 int32_t DoNotStartEMM
= 0;
3602 #if defined(WITH_COOLAPI) || defined(WITH_COOLAPI2)
3603 // Don't start and Stop EMM Filters over and over again if we are on FTA
3604 if (dvbapi_client
->last_caid
== NO_CAID_VALUE
) {
3609 if(cfg
.dvbapi_au
> 0 && demux
[demux_id
].EMMpidcount
== 0 && !DoNotStartEMM
) // only do emm setup if au enabled and not running!
3611 demux
[demux_id
].emm_filter
= -1; // to register first run emmfilter start
3612 if(demux
[demux_id
].emmstart
.time
== 1) // irdeto fetch emm cat direct!
3614 cs_ftime(&demux
[demux_id
].emmstart
); // trick to let emm fetching start after 30 seconds to speed up zapping
3615 dvbapi_start_filter(demux_id
, demux
[demux_id
].pidindex
, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM
); //CAT
3617 else { cs_ftime(&demux
[demux_id
].emmstart
); } // for all other caids delayed start!
3623 static uint32_t dvbapi_extract_sdt_string(char *buf
, uint32_t buflen
, uint8_t* source
, uint32_t sourcelen
)
3625 uint32_t i
, j
, offset
= 0;
3626 int8_t iso_mode
= -1;
3628 const unsigned char *ptr_in
;
3629 unsigned char *ptr_out
;
3630 size_t in_bytes
, out_bytes
;
3638 if(!cs_malloc(&tmpbuf
, buflen
))
3643 if((sourcelen
+ 1) > buflen
)
3644 { sourcelen
= buflen
- 1; }
3646 if(sourcelen
> 0 && source
[0] < 0x20)
3649 if(source
[0] >= 0x01 && source
[0] <= 0x0B && source
[0] != 0x08)
3650 { offset
= 1; iso_mode
= 4+source
[0]; }
3653 else if(source
[0] == 0x10 && source
[1] == 0x00
3654 && source
[2] >= 0x01 && source
[2] <= 0x0F && source
[2] != 0x0C)
3655 { offset
= 3; iso_mode
= source
[2]; }
3658 else if(source
[0] == 0x11)
3659 { offset
= 1; iso_mode
= -2;}
3661 //missing: 0x12 Korean Character Set KSC5601-1987
3662 //missing: 0x13 Simplified Chinese Character Set GB-2312-1980
3663 //missing: 0x14 Big5 subset of ISO/IEC 10646-1 (Traditional Chinese)
3666 else if(source
[0] == 0x15)
3667 { offset
= 1; iso_mode
= -3;}
3669 //missing: 0x1F Described by encoding_type_id *standard not finished yet*
3671 //Reserved for future use
3673 { NULLFREE(tmpbuf
); return 0; }
3676 if(offset
>= sourcelen
)
3677 { NULLFREE(tmpbuf
); return 0; }
3681 for(i
=0, j
=0; i
<(sourcelen
-offset
); i
++)
3683 if(((uint8_t)source
[offset
+i
]) >= 0x80 && ((uint8_t)source
[offset
+i
]) <= 0x9F)
3688 tmpbuf
[j
] = source
[offset
+i
];
3694 ptr_in
= (const unsigned char *)tmpbuf
;
3695 in_bytes
= strlen(tmpbuf
);
3696 ptr_out
= (unsigned char *)buf
;
3699 #ifdef READ_SDT_CHARSETS
3702 memset(buf
, 0, buflen
);
3704 cs_log_dbg(D_DVBAPI
, "sdt-info dbg: iso_mode: %d offset: %u", iso_mode
, offset
);
3705 cs_log_dump_dbg(D_DVBAPI
, (uint8_t*)tmpbuf
, in_bytes
, "sdt-info dbg: raw string: ");
3709 if(ISO6937toUTF8(&ptr_in
, &in_bytes
, &ptr_out
, &out_bytes
) == (size_t)(-1))
3711 cs_log_dbg(D_DVBAPI
, "sdt-info error: ISO6937toUTF8 failed");
3718 if(ISO8859toUTF8(iso_mode
, &ptr_in
, &in_bytes
, &ptr_out
, &out_bytes
) == (size_t)(-1))
3720 cs_log_dbg(D_DVBAPI
, "sdt-info error: ISO8859toUTF8 failed");
3729 cs_strncpy(buf
, tmpbuf
, buflen
);
3730 cs_log_dbg(D_DVBAPI
, "sdt-info warning: your build of oscam does not support iso-to-utf8 conversion, special chars may be corrupted!");
3734 else if(iso_mode
== -2)
3736 memset(buf
, 0, buflen
);
3738 cs_log_dbg(D_DVBAPI
, "sdt-info dbg: iso_mode: %d offset: %u", iso_mode
, offset
);
3740 if(UnicodetoUTF8(&ptr_in
, &in_bytes
, &ptr_out
, &out_bytes
) == (size_t)(-1))
3742 cs_log_dbg(D_DVBAPI
, "sdt-info error: UnicodetoUTF8 failed");
3748 else if(iso_mode
== -3)
3750 memcpy(buf
, source
+offset
, sourcelen
-offset
);
3751 buf
[sourcelen
-offset
] = '\0';
3753 cs_log_dbg(D_DVBAPI
, "sdt-info dbg: iso_mode: -3 offset: %u", offset
);
3756 cs_log_dump_dbg(D_DVBAPI
, (uint8_t*)buf
, strlen(buf
), "sdt-info dbg: encoded string: ");
3762 static void dvbapi_create_srvid_line(int32_t demux_id
, char *buffer
, uint32_t buflen
)
3765 uint16_t caid_done
[32], cur_caid
;
3766 uint8_t caid_done_count
= 0, skip_caid
;
3769 if(demux
[demux_id
].ECMpidcount
== 0)
3771 snprintf(buffer
, buflen
, "%04X@%06X", NO_CAID_VALUE
, NO_PROVID_VALUE
);
3775 for(i
=0; i
< demux
[demux_id
].ECMpidcount
&& i
< 32; i
++)
3779 for(j
=0; j
< caid_done_count
; j
++)
3781 if(caid_done
[j
] == demux
[demux_id
].ECMpids
[i
].CAID
)
3793 cur_caid
= demux
[demux_id
].ECMpids
[i
].CAID
;
3794 pos
+= snprintf(buffer
+pos
, buflen
-pos
, "%s%04X", caid_done_count
> 0 ? "," : "", cur_caid
== 0 ? NO_CAID_VALUE
: cur_caid
);
3796 for(j
=i
; j
< demux
[demux_id
].ECMpidcount
; j
++)
3798 if(demux
[demux_id
].ECMpids
[j
].PROVID
== 0)
3803 if(cur_caid
== demux
[demux_id
].ECMpids
[j
].CAID
)
3805 pos
+= snprintf(buffer
+pos
, buflen
-pos
, "@%06X", demux
[demux_id
].ECMpids
[j
].PROVID
);
3809 caid_done
[caid_done_count
] = demux
[demux_id
].ECMpids
[i
].CAID
;
3814 static const char *dvbapi_get_service_type(uint8_t service_type_id
)
3816 switch(service_type_id
)
3836 static void dvbapi_parse_sdt(int32_t demux_id
, unsigned char *buffer
, uint32_t length
, uint32_t msgid
)
3838 uint8_t tag
, data_length
= 0, provider_name_length
, service_name_length
, service_type
;
3839 uint16_t service_id
, descriptor_length
, dpos
;
3840 int32_t provid
, caid
;
3841 uint32_t section_length
, pos
;
3843 char provider_name
[64], service_name
[64], tmp
[256], srvid_line
[1024];
3845 FILE *fpsave
= NULL
;
3846 int8_t did_save_srvid
= 0;
3848 cs_log_dump_dbg(D_DVBAPI
, buffer
, length
, "sdt-info dbg: sdt data: ");
3853 if(buffer
[0] != 0x42)
3856 section_length
= b2i(2, buffer
+ 1) &0xFFF;
3858 if(section_length
+3 != length
)
3861 for(pos
= 11; pos
+5 < length
; pos
+= descriptor_length
)
3863 service_id
= b2i(2, buffer
+ pos
);
3864 descriptor_length
= b2i(2, buffer
+ pos
+ 3) &0xFFF;
3866 if((pos
+5+descriptor_length
) >= length
)
3871 if(service_id
!= demux
[demux_id
].program_number
)
3874 for(dpos
= 0; dpos
+1 < descriptor_length
; dpos
+= (2 + data_length
))
3876 tag
= buffer
[pos
+dpos
];
3877 data_length
= buffer
[pos
+dpos
+1];
3879 if(dpos
+1+data_length
>= descriptor_length
)
3885 if(dpos
+3 >= descriptor_length
)
3888 service_type
= buffer
[pos
+dpos
+2];
3890 provider_name_length
= buffer
[pos
+dpos
+3];
3891 if((dpos
+4+provider_name_length
+1) > descriptor_length
)
3894 service_name_length
= buffer
[pos
+dpos
+4+provider_name_length
];
3895 if((dpos
+4+provider_name_length
+1+service_name_length
) > descriptor_length
)
3898 pidindex
= demux
[demux_id
].pidindex
;
3902 provid
= demux
[demux_id
].ECMpids
[pidindex
].PROVID
;
3903 caid
= demux
[demux_id
].ECMpids
[pidindex
].CAID
;
3907 if(demux
[demux_id
].ECMpidcount
== 0 || demux
[demux_id
].ECMpids
[0].CAID
== 0)
3909 caid
= NO_CAID_VALUE
;
3910 provid
= NO_PROVID_VALUE
;
3914 caid
= demux
[demux_id
].ECMpids
[0].CAID
;
3915 provid
= demux
[demux_id
].ECMpids
[0].PROVID
;
3919 if(!dvbapi_extract_sdt_string(provider_name
, sizeof(provider_name
), buffer
+pos
+dpos
+4, provider_name_length
))
3922 if(!dvbapi_extract_sdt_string(service_name
, sizeof(service_name
), buffer
+pos
+dpos
+4+provider_name_length
+1, service_name_length
))
3925 cs_log_dbg(D_DVBAPI
,"sdt-info (provider: %s - channel: %s)", provider_name
, service_name
);
3927 dvbapi_stop_filter(demux_id
, TYPE_SDT
, msgid
);
3929 if(strlen(provider_name
) && caid
!= NO_CAID_VALUE
)
3931 get_providername_or_null(provid
, caid
, tmp
, sizeof(tmp
));
3935 get_config_filename(tmp
, sizeof(tmp
), "oscam.provid");
3937 if((fpsave
= fopen(tmp
, "a")))
3939 fprintf(fpsave
, "\n%04X@%06X|%s|", caid
, provid
, provider_name
);
3947 if(strlen(service_name
))
3949 get_servicename_or_null(cur_client(), service_id
, provid
, caid
, tmp
, sizeof(tmp
));
3953 type
= dvbapi_get_service_type(service_type
);
3955 get_config_filename(tmp
, sizeof(tmp
), "oscam.srvid2");
3957 if(!access(tmp
, F_OK
) && (fpsave
= fopen(tmp
, "a")))
3959 if((caid
!= NO_CAID_VALUE
) || (cfg
.dvbapi_read_sdt
> 1))
3961 dvbapi_create_srvid_line(demux_id
, srvid_line
, sizeof(srvid_line
));
3963 if(cfg
.dvbapi_write_sdt_prov
)
3964 { fprintf(fpsave
, "\n%04X:%s|%s|%s||%s", service_id
, srvid_line
, service_name
, type
, provider_name
); }
3966 { fprintf(fpsave
, "\n%04X:%s|%s|%s", service_id
, srvid_line
, service_name
, type
); }
3973 get_config_filename(tmp
, sizeof(tmp
), "oscam.srvid");
3975 if((fpsave
= fopen(tmp
, "a")))
3977 if((caid
!= NO_CAID_VALUE
) || (cfg
.dvbapi_read_sdt
> 1))
3979 dvbapi_create_srvid_line(demux_id
, srvid_line
, sizeof(srvid_line
));
3981 if(cfg
.dvbapi_write_sdt_prov
)
3982 { fprintf(fpsave
, "\n%s:%04X|%s|%s|%s", srvid_line
, service_id
, provider_name
, service_name
, type
); }
3985 { fprintf(fpsave
, "\n%s:%04X||%s|%s", srvid_line
, service_id
, service_name
, type
); }
4005 static void dvbapi_parse_pat(int32_t demux_id
, unsigned char *buffer
, uint32_t length
, uint32_t msgid
)
4010 dvbapi_stop_filter(demux_id
, TYPE_PAT
, msgid
);
4012 for(i
=8; i
+7<length
; i
+=4)
4014 srvid
= b2i(2, buffer
+i
);
4019 if(demux
[demux_id
].program_number
== srvid
)
4021 dvbapi_start_pmt_filter(demux_id
, b2i(2, buffer
+i
+2) & 0x1FFF);
4027 int32_t dvbapi_init_listenfd(void)
4029 int32_t clilen
, listenfd
;
4030 struct sockaddr_un servaddr
;
4032 memset(&servaddr
, 0, sizeof(struct sockaddr_un
));
4033 servaddr
.sun_family
= AF_UNIX
;
4034 cs_strncpy(servaddr
.sun_path
, devices
[selected_box
].cam_socket_path
, sizeof(servaddr
.sun_path
));
4035 clilen
= sizeof(servaddr
.sun_family
) + strlen(servaddr
.sun_path
);
4037 if((unlink(devices
[selected_box
].cam_socket_path
) < 0) && (errno
!= ENOENT
))
4039 if((listenfd
= socket(AF_UNIX
, SOCK_STREAM
, 0)) < 0)
4041 if(bind(listenfd
, (struct sockaddr
*)&servaddr
, clilen
) < 0)
4043 if(listen(listenfd
, 5) < 0)
4046 // change the access right on the camd.socket
4047 // this will allow oscam to run as root if needed
4048 // and still allow non root client to connect to the socket
4049 chmod(devices
[selected_box
].cam_socket_path
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
4054 int32_t dvbapi_net_init_listenfd(void)
4057 struct SOCKADDR servaddr
;
4059 memset(&servaddr
, 0, sizeof(servaddr
));
4060 SIN_GET_FAMILY(servaddr
) = DEFAULT_AF
;
4061 SIN_GET_ADDR(servaddr
) = ADDR_ANY
;
4062 SIN_GET_PORT(servaddr
) = htons((uint16_t)cfg
.dvbapi_listenport
);
4064 if((listenfd
= socket(DEFAULT_AF
, SOCK_STREAM
, 0)) < 0)
4070 // azbox toolchain do not have this define
4072 #define IPV6_V6ONLY 26
4075 // set the server socket option to listen on IPv4 and IPv6 simultaneously
4076 setsockopt(listenfd
, IPPROTO_IPV6
, IPV6_V6ONLY
, (void *)&opt
, sizeof(opt
));
4080 setsockopt(listenfd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&opt
, sizeof(opt
));
4081 set_so_reuseport(listenfd
);
4083 if(bind(listenfd
, (struct sockaddr
*)&servaddr
, sizeof(servaddr
)) < 0)
4085 if(listen(listenfd
, 5) < 0)
4091 static pthread_mutex_t event_handler_lock
= PTHREAD_MUTEX_INITIALIZER
;
4093 void event_handler(int32_t UNUSED(signal
))
4095 struct stat pmt_info
;
4098 struct dirent entry
, *dp
= NULL
;
4100 uchar mbuf
[2048]; // dirty fix: larger buffer needed for CA PMT mode 6 with many parallel channels to decode
4101 if(dvbapi_client
!= cur_client()) { return; }
4103 SAFE_MUTEX_LOCK(&event_handler_lock
);
4105 if(cfg
.dvbapi_boxtype
== BOXTYPE_PC
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
|| cfg
.dvbapi_boxtype
== BOXTYPE_SAMYGO
)
4109 int32_t standby_fd
= open(STANDBY_FILE
, O_RDONLY
);
4110 pausecam
= (standby_fd
> 0) ? 1 : 0;
4113 int32_t ret
= close(standby_fd
);
4114 if(ret
< 0) { cs_log("ERROR: Could not close standby fd (errno=%d %s)", errno
, strerror(errno
)); }
4118 if(cfg
.dvbapi_boxtype
== BOXTYPE_IPBOX
|| cfg
.dvbapi_pmtmode
== 1)
4120 SAFE_MUTEX_UNLOCK(&event_handler_lock
);
4124 for(i
= 0; i
< MAX_DEMUX
; i
++)
4126 if(demux
[i
].pmt_file
[0] != 0)
4128 snprintf(dest
, sizeof(dest
), "%s%s", TMPDIR
, demux
[i
].pmt_file
);
4129 pmt_fd
= open(dest
, O_RDONLY
);
4132 if(fstat(pmt_fd
, &pmt_info
) != 0)
4134 int32_t ret
= close(pmt_fd
);
4135 if(ret
< 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno
, strerror(errno
)); }
4139 if((time_t)pmt_info
.st_mtime
!= demux
[i
].pmt_time
)
4141 dvbapi_stop_descrambling(i
, 0);
4144 int32_t ret
= close(pmt_fd
);
4145 if(ret
< 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno
, strerror(errno
)); }
4150 cs_log("Demuxer %d Unable to open PMT file %s -> stop descrambling!", i
, dest
);
4151 dvbapi_stop_descrambling(i
, 0);
4156 if(disable_pmt_files
)
4158 SAFE_MUTEX_UNLOCK(&event_handler_lock
);
4162 dirp
= opendir(TMPDIR
);
4165 cs_log_dbg(D_DVBAPI
, "opendir failed (errno=%d %s)", errno
, strerror(errno
));
4166 SAFE_MUTEX_UNLOCK(&event_handler_lock
);
4170 while(!cs_readdir_r(dirp
, &entry
, &dp
))
4174 if(strlen(dp
->d_name
) < 7)
4176 if(strncmp(dp
->d_name
, "pmt", 3) != 0 || strncmp(dp
->d_name
+ strlen(dp
->d_name
) - 4, ".tmp", 4) != 0)
4178 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
4179 struct s_dvbapi_priority
*p
;
4180 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
) // stapi: check if there is a device connected to this pmt file!
4182 if(p
->type
!= 's') { continue; } // stapi rule?
4183 if(strcmp(dp
->d_name
, p
->pmtfile
) != 0) { continue; } // same file?
4184 break; // found match!
4188 cs_log_dbg(D_DVBAPI
, "No matching S: line in oscam.dvbapi for pmtfile %s -> skip!", dp
->d_name
);
4192 snprintf(dest
, sizeof(dest
), "%s%s", TMPDIR
, dp
->d_name
);
4193 pmt_fd
= open(dest
, O_RDONLY
);
4197 if(fstat(pmt_fd
, &pmt_info
) != 0)
4199 int32_t ret
= close(pmt_fd
);
4200 if(ret
< 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno
, strerror(errno
)); }
4205 for(i
= 0; i
< MAX_DEMUX
; i
++)
4207 if(strcmp(demux
[i
].pmt_file
, dp
->d_name
) == 0)
4209 if((time_t)pmt_info
.st_mtime
== demux
[i
].pmt_time
)
4218 int32_t ret
= close(pmt_fd
);
4219 if(ret
< 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno
, strerror(errno
)); }
4223 cs_log_dbg(D_DVBAPI
, "found pmt file %s", dest
);
4226 uint32_t len
= read(pmt_fd
, mbuf
, sizeof(mbuf
));
4227 int32_t ret
= close(pmt_fd
);
4228 if(ret
< 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno
, strerror(errno
)); }
4232 cs_log_dbg(D_DVBAPI
, "pmt file %s have invalid len!", dest
);
4240 // QboxHD pmt.tmp is the full capmt written as a string of hex values
4241 // pmt.tmp must be longer than 3 bytes (6 hex chars) and even length
4242 if((len
< 6) || ((len
% 2) != 0) || ((len
/ 2) > sizeof(dest
)))
4244 cs_log_dbg(D_DVBAPI
, "error parsing QboxHD pmt.tmp, incorrect length");
4248 for(j2
= 0, j1
= 0; j2
< len
; j2
+= 2, j1
++)
4251 if(sscanf((char *)mbuf
+ j2
, "%02X", &tmp
) != 1)
4253 cs_log_dbg(D_DVBAPI
, "error parsing QboxHD pmt.tmp, data not valid in position %d", j2
);
4254 SAFE_MUTEX_UNLOCK(&event_handler_lock
);
4259 memcpy(dest
+ j1
, &tmp
, 4);
4263 cs_log_dump_dbg(D_DVBAPI
, (unsigned char *)dest
, len
/ 2, "QboxHD pmt.tmp:");
4264 pmt_id
= dvbapi_parse_capmt((unsigned char *)dest
+ 4, (len
/ 2) - 4, -1, dp
->d_name
, 0, 0, 0);
4266 if(len
> sizeof(dest
))
4268 cs_log_dbg(D_DVBAPI
, "event_handler() dest buffer is to small for pmt data!");
4273 cs_log_dbg(D_DVBAPI
, "event_handler() received pmt is too small! (%d < 16 bytes!)", len
);
4276 cs_log_dump_dbg(D_DVBAPI
, mbuf
, len
, "pmt:");
4281 uint32_t pmt_program_length
= b2i(2, mbuf
+ 10)&0xFFF;
4282 i2b_buf(2, pmt_program_length
+ 1, (uchar
*) dest
+ 4);
4285 memcpy(dest
+ 7, mbuf
+ 12, len
- 12 - 4);
4287 pmt_id
= dvbapi_parse_capmt((uchar
*)dest
, 7 + len
- 12 - 4, -1, dp
->d_name
, 0, 0, 0, 0);
4292 cs_strncpy(demux
[pmt_id
].pmt_file
, dp
->d_name
, sizeof(demux
[pmt_id
].pmt_file
));
4293 demux
[pmt_id
].pmt_time
= (time_t)pmt_info
.st_mtime
;
4296 if(cfg
.dvbapi_pmtmode
== 3)
4298 disable_pmt_files
= 1;
4303 SAFE_MUTEX_UNLOCK(&event_handler_lock
);
4306 void *dvbapi_event_thread(void *cli
)
4308 struct s_client
*client
= (struct s_client
*) cli
;
4309 SAFE_SETSPECIFIC(getclient
, client
);
4310 set_thread_name(__func__
);
4320 void dvbapi_process_input(int32_t demux_id
, int32_t filter_num
, uchar
*buffer
, int32_t len
, uint32_t msgid
)
4322 struct s_ecmpids
*curpid
= NULL
;
4323 int32_t pid
= demux
[demux_id
].demux_fd
[filter_num
].pidindex
;
4324 uint16_t filtertype
= demux
[demux_id
].demux_fd
[filter_num
].type
;
4325 uint32_t sctlen
= SCT_LEN(buffer
);
4327 if((uint32_t) len
< sctlen
) // invalid CAT length
4329 cs_log_dbg(D_DVBAPI
, "Received filterdata with total length 0x%03X but section length is 0x%03X -> invalid length!", len
, sctlen
);
4333 if(demux_id
< 0 || demux_id
>= MAX_DEMUX
)
4335 cs_log("dvbapi_process_input(): error - received invalid demux_id (%d)", demux_id
);
4339 if(filter_num
< 0 || filter_num
>= MAX_FILTER
)
4341 cs_log("dvbapi_process_input(): error - received invalid filter_num (%d)", filter_num
);
4345 if(pid
!= -1 && filtertype
== TYPE_ECM
)
4347 curpid
= &demux
[demux_id
].ECMpids
[pid
];
4350 int32_t filt_match
= filtermatch(buffer
, filter_num
, demux_id
, sctlen
); // acts on all filters (sdt/emm/ecm)
4353 cs_log_dbg(D_DVBAPI
,"Demuxer %d receiver returned data that was not matching to the filter -> delivered filter data discarded!", demux_id
);
4357 if(curpid
&& curpid
->tries
<= 0xF0 && filtertype
== TYPE_ECM
)
4359 curpid
->irdeto_maxindex
= 0;
4360 curpid
->irdeto_curindex
= 0xFE;
4361 curpid
->tries
= 0xFE; // reset timeout retry flag
4362 curpid
->irdeto_cycle
= 0xFE; // reset irdetocycle
4364 curpid
->checked
= 4; // flag ecmpid as checked
4365 curpid
->status
= -1; // flag ecmpid as unusable
4366 if(pid
== demux
[demux_id
].pidindex
)
4368 demux
[demux_id
].pidindex
= -1; // current pid delivered problems so this pid isnt being used to descramble any longer-> clear pidindex
4369 dvbapi_edit_channel_cache(demux_id
, pid
, 0); // remove this pid from channelcache since we had no founds on any ecmpid!
4371 dvbapi_stop_filternum(demux_id
, filter_num
, msgid
); // stop this ecm filter!
4375 if(filtertype
== TYPE_ECM
)
4377 uint32_t chid
= 0x10000;
4380 if(len
!= 0) // len = 0 receiver encountered an internal bufferoverflow!
4382 cs_log_dump_dbg(D_DVBAPI
, buffer
, sctlen
, "Demuxer %d Filter %d fetched ECM data (ecmlength = 0x%03X):", demux_id
, filter_num
+ 1, sctlen
);
4384 if(sctlen
> MAX_ECM_SIZE
) // ecm too long to handle!
4386 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
);
4389 curpid
->tries
-=0x0E;
4394 if(!(buffer
[0] == 0x80 || buffer
[0] == 0x81))
4396 cs_log_dbg(D_DVBAPI
, "Received an ECM with invalid ecmtable ID %02X -> ignoring!", buffer
[0]);
4404 if(curpid
->table
== buffer
[0] && !caid_is_irdeto(curpid
->CAID
)) // wait for odd / even ecm change (only not for irdeto!)
4407 if(!(er
= get_ecmtask()))
4412 er
->srvid
= demux
[demux_id
].program_number
;
4415 cs_strncpy(er
->dev_name
, dev_list
[demux
[demux_id
].dev_index
].name
, sizeof(dev_list
[demux
[demux_id
].dev_index
].name
));
4418 er
->tsid
= demux
[demux_id
].tsid
;
4419 er
->onid
= demux
[demux_id
].onid
;
4420 er
->pmtpid
= demux
[demux_id
].pmtpid
;
4421 er
->ens
= demux
[demux_id
].enigma_namespace
;
4423 er
->caid
= curpid
->CAID
;
4424 er
->pid
= curpid
->ECM_PID
;
4425 er
->prid
= curpid
->PROVID
;
4426 er
->vpid
= curpid
->VPID
;
4427 er
->ecmlen
= sctlen
;
4428 memcpy(er
->ecm
, buffer
, er
->ecmlen
);
4429 chid
= get_subid(er
); // fetch chid or fake chid
4432 dvbapi_set_section_filter(demux_id
, er
, filter_num
);
4437 if(caid_is_irdeto(curpid
->CAID
))
4439 // 80 70 39 53 04 05 00 88
4440 // 81 70 41 41 01 06 00 13 00 06 80 38 1F 52 93 D2
4441 //if (buffer[5]>20) return;
4442 if(curpid
->irdeto_maxindex
!= buffer
[5]) //6, register max irdeto index
4444 cs_log_dbg(D_DVBAPI
, "Found %d IRDETO ECM CHIDs", buffer
[5] + 1);
4445 curpid
->irdeto_maxindex
= buffer
[5]; // numchids = 7 (0..6)
4450 if(!(er
= get_ecmtask()))
4455 er
->srvid
= demux
[demux_id
].program_number
;
4458 cs_strncpy(er
->dev_name
, dev_list
[demux
[demux_id
].dev_index
].name
, sizeof(dev_list
[demux
[demux_id
].dev_index
].name
));
4461 er
->tsid
= demux
[demux_id
].tsid
;
4462 er
->onid
= demux
[demux_id
].onid
;
4463 er
->pmtpid
= demux
[demux_id
].pmtpid
;
4464 er
->ens
= demux
[demux_id
].enigma_namespace
;
4466 er
->caid
= curpid
->CAID
;
4467 er
->pid
= curpid
->ECM_PID
;
4468 er
->prid
= curpid
->PROVID
;
4469 er
->vpid
= curpid
->VPID
;
4470 er
->ecmlen
= sctlen
;
4471 memcpy(er
->ecm
, buffer
, er
->ecmlen
);
4474 chid
= get_subid(er
); // fetch chid or fake chid
4475 uint32_t fixedprovid
= chk_provid(er
->ecm
, er
->caid
);
4476 if(fixedprovid
&& fixedprovid
!= er
->prid
)
4478 cs_log_dbg(D_DVBAPI
, "Fixing provid ecmpid %d from %06X -> %06X", pid
, curpid
->PROVID
, fixedprovid
);
4479 curpid
->PROVID
= fixedprovid
;
4482 cs_log_dbg(D_DVBAPI
, "Fixing provid filter %d from %06X -> %06X", filter_num
+1, demux
[demux_id
].demux_fd
[filter_num
].provid
, fixedprovid
);
4483 demux
[demux_id
].demux_fd
[filter_num
].provid
= fixedprovid
;
4485 cs_log_dbg(D_DVBAPI
, "Fixing provid ecmrequest from %06X -> %06X", er
->prid
, fixedprovid
);
4486 er
->prid
= fixedprovid
;
4490 if(len
== 0) // only used on receiver internal bufferoverflow to get quickly fresh ecm filterdata otherwise freezing!
4493 dvbapi_set_section_filter(demux_id
, er
, filter_num
);
4498 if(caid_is_irdeto(curpid
->CAID
))
4501 if(curpid
->irdeto_curindex
!= buffer
[4]) // old style wrong irdeto index
4503 if(curpid
->irdeto_curindex
== 0xFE) // check if this ecmfilter just started up
4505 curpid
->irdeto_curindex
= buffer
[4]; // on startup set the current index to the irdeto index of the ecm
4507 else // we are already running and not interested in this ecm
4509 if(curpid
->table
!= buffer
[0]) curpid
->table
= 0; // fix for receivers not supporting section filtering
4510 dvbapi_set_section_filter(demux_id
, er
, filter_num
); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4515 else //fix for receivers not supporting section filtering
4517 if(curpid
->table
== buffer
[0]){
4522 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
);
4526 cs_log_dbg(D_DVBAPI
, "Demuxer %d ECMTYPE %02X CAID %04X PROVID %06X ECMPID %04X FAKECHID %04X (unique part in ecm)",
4527 demux_id
, er
->ecm
[0], er
->caid
, er
->prid
, er
->pid
, er
->chid
);
4530 // check for matching chid (unique ecm part in case of non-irdeto cas) + added fix for seca2 monthly changing fakechid
4531 if((curpid
->CHID
< 0x10000) && !((chid
== curpid
->CHID
) || ((curpid
->CAID
>> 8 == 0x01) && (chid
&0xF0FF) == (curpid
->CHID
&0xF0FF)) ) )
4533 if(caid_is_irdeto(curpid
->CAID
))
4536 if((curpid
->irdeto_cycle
< 0xFE) && (curpid
->irdeto_cycle
== curpid
->irdeto_curindex
)) // if same: we cycled all indexes but no luck!
4538 struct s_dvbapi_priority
*forceentry
= dvbapi_check_prio_match(demux_id
, pid
, 'p');
4539 if(!forceentry
|| !forceentry
->force
) // forced pid? keep trying the forced ecmpid, no force kill ecm filter
4541 if(curpid
->checked
== 2) { curpid
->checked
= 4; }
4542 if(curpid
->checked
== 1)
4544 curpid
->checked
= 2;
4545 curpid
->CHID
= 0x10000;
4547 dvbapi_stop_filternum(demux_id
, filter_num
, msgid
); // stop this ecm filter!
4553 curpid
->irdeto_curindex
++; // set check on next index
4554 if(curpid
->irdeto_cycle
== 0xFE) curpid
->irdeto_cycle
= buffer
[4]; // on startup set to current irdeto index
4555 if(curpid
->irdeto_curindex
> curpid
->irdeto_maxindex
) { curpid
->irdeto_curindex
= 0; } // check if we reached max irdeto index, if so reset to 0
4558 dvbapi_set_section_filter(demux_id
, er
, filter_num
); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4562 else // all nonirdeto cas systems
4564 struct s_dvbapi_priority
*forceentry
= dvbapi_check_prio_match(demux_id
, pid
, 'p');
4566 dvbapi_set_section_filter(demux_id
, er
, filter_num
); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4567 if(forceentry
&& forceentry
->force
)
4570 return; // forced pid? keep trying the forced ecmpid!
4572 if(curpid
->checked
== 2) { curpid
->checked
= 4; }
4573 if(curpid
->checked
== 1)
4575 curpid
->checked
= 2;
4576 curpid
->CHID
= 0x10000;
4578 dvbapi_stop_filternum(demux_id
, filter_num
, msgid
); // stop this ecm filter!
4584 struct s_dvbapi_priority
*p
;
4586 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
)
4589 || (p
->caid
&& p
->caid
!= curpid
->CAID
)
4590 || (p
->provid
&& p
->provid
!= curpid
->PROVID
)
4591 || (p
->ecmpid
&& p
->ecmpid
!= curpid
->ECM_PID
)
4592 || (p
->srvid
&& p
->srvid
!= demux
[demux_id
].program_number
))
4595 if((uint
)p
->delay
== sctlen
&& p
->force
< 6)
4606 { curpid
->PROVID
= chk_provid(buffer
, curpid
->CAID
); }
4608 if(caid_is_irdeto(curpid
->CAID
)) // irdeto: wait for the correct index
4610 if(buffer
[4] != curpid
->irdeto_curindex
)
4613 dvbapi_set_section_filter(demux_id
, er
, filter_num
); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4618 // we have an ecm with the correct irdeto index (or fakechid)
4619 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
) // check for ignore!
4622 || (p
->caid
&& p
->caid
!= curpid
->CAID
)
4623 || (p
->provid
&& p
->provid
!= curpid
->PROVID
)
4624 || (p
->ecmpid
&& p
->ecmpid
!= curpid
->ECM_PID
)
4625 || (p
->pidx
&& p
->pidx
-1 != pid
)
4626 || (p
->srvid
&& p
->srvid
!= demux
[demux_id
].program_number
))
4629 if(p
->type
== 'i' && (p
->chid
< 0x10000 && p
->chid
== chid
)) // found a ignore chid match with current ecm -> ignoring this irdeto index
4631 curpid
->irdeto_curindex
++;
4632 if(curpid
->irdeto_cycle
== 0xFE) curpid
->irdeto_cycle
= buffer
[4]; // on startup set to current irdeto index
4633 if(curpid
->irdeto_curindex
> curpid
->irdeto_maxindex
) // check if curindex is over the max
4635 curpid
->irdeto_curindex
= 0;
4638 if(caid_is_irdeto(curpid
->CAID
) && (curpid
->irdeto_cycle
!= curpid
->irdeto_curindex
)) // irdeto: wait for the correct index + check if we cycled all
4640 dvbapi_set_section_filter(demux_id
, er
, filter_num
); // set ecm filter to odd + even since this chid has to be ignored!
4642 else // this fakechid has to be ignored, kill this filter!
4644 if(curpid
->checked
== 2) { curpid
->checked
= 4; }
4645 if(curpid
->checked
== 1)
4647 curpid
->checked
= 2;
4648 curpid
->CHID
= 0x10000;
4650 dvbapi_stop_filternum(demux_id
, filter_num
, msgid
); // stop this ecm filter!
4657 if(er
) curpid
->table
= er
->ecm
[0];
4658 request_cw(dvbapi_client
, er
, demux_id
, 1); // register this ecm for delayed ecm response check
4659 return; // end of ecm filterhandling!
4662 if(filtertype
== TYPE_EMM
)
4664 if(len
!= 0) // len = 0 receiver encountered an internal bufferoverflow!
4666 cs_log_dump_dbg(D_DVBAPI
, buffer
, sctlen
, "Demuxer %d Filter %d fetched EMM data (emmlength = 0x%03X):", demux_id
, filter_num
+ 1, sctlen
);
4668 if(sctlen
> MAX_EMM_SIZE
) // emm too long to handle!
4670 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
);
4676 return; // just skip on internal bufferoverflow
4680 if(demux
[demux_id
].demux_fd
[filter_num
].pid
== 0x01) // CAT
4682 cs_log_dbg(D_DVBAPI
, "receiving cat");
4683 dvbapi_parse_cat(demux_id
, buffer
, sctlen
);
4685 dvbapi_stop_filternum(demux_id
, filter_num
, msgid
);
4688 dvbapi_process_emm(demux_id
, filter_num
, buffer
, sctlen
);
4691 if(filtertype
== TYPE_SDT
)
4693 cs_log_dump_dbg(D_DVBAPI
, buffer
, sctlen
, "Demuxer %d Filter %d fetched SDT data (length = 0x%03X):", demux_id
, filter_num
+ 1, sctlen
);
4694 dvbapi_parse_sdt(demux_id
, buffer
, sctlen
, msgid
);
4697 if(filtertype
== TYPE_PAT
)
4699 cs_log_dump_dbg(D_DVBAPI
, buffer
, sctlen
, "Demuxer %d Filter %d fetched PAT data (length = 0x%03X):", demux_id
, filter_num
+ 1, sctlen
);
4700 dvbapi_parse_pat(demux_id
, buffer
, sctlen
, msgid
);
4703 if(filtertype
== TYPE_PMT
)
4705 cs_log_dump_dbg(D_DVBAPI
, buffer
, sctlen
, "Demuxer %d Filter %d fetched CAPMT data (length = 0x%03X):", demux_id
, filter_num
+ 1, sctlen
);
4706 dvbapi_parse_capmt(buffer
, sctlen
, demux
[demux_id
].socket_fd
, demux
[demux_id
].pmt_file
, 1, demux_id
, demux
[demux_id
].client_proto_version
, msgid
);
4710 static int32_t dvbapi_recv(int32_t connfd
, uchar
* mbuf
, size_t rlen
)
4712 ssize_t len
= cs_recv(connfd
, mbuf
, rlen
, MSG_DONTWAIT
);
4714 if((len
== -1 && (errno
!= EINTR
&& errno
!= EAGAIN
&& errno
!= EWOULDBLOCK
)) || (len
== 0))
4727 static uint16_t dvbapi_get_nbof_missing_header_bytes(uchar
* mbuf
, uint16_t mbuf_len
)
4731 return 4 - mbuf_len
;
4734 uint32_t opcode
= b2i(4, mbuf
); //get the client opcode (4 bytes)
4736 //detect the opcode, its size (chunksize) and its internal data size (data_len)
4737 if((opcode
& 0xFFFFF000) == DVBAPI_AOT_CA
) // min 4+size bytes
4741 uint32_t size
= mbuf
[3] & 0x7F;
4743 if(mbuf_len
< (4+size
))
4745 return (4+size
) - mbuf_len
;
4750 else switch (opcode
)
4752 case DVBAPI_FILTER_DATA
: // min 9 bytes
4756 return 9 - mbuf_len
;
4760 case DVBAPI_CLIENT_INFO
: // min 7 bytes
4764 return 7 - mbuf_len
;
4775 static void dvbapi_get_packet_size(uchar
* mbuf
, uint16_t mbuf_len
, uint16_t* chunksize
, uint16_t *data_len
, uint16_t client_proto_version
)
4777 //chunksize: size of complete chunk in the buffer (an opcode with the data)
4778 //data_len: variable for internal data length (eg. for the filter data size, PMT len)
4779 uint32_t msgid_size
= 0;
4784 if (client_proto_version
>= 3)
4787 if(mbuf_len
< 4 + msgid_size
)
4789 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16
") too short", mbuf_len
);
4796 uint32_t opcode
= b2i(4, mbuf
); //get the client opcode (4 bytes)
4798 //detect the opcode, its size (chunksize) and its internal data size (data_len)
4799 if((opcode
& 0xFFFFF000) == DVBAPI_AOT_CA
) // min 4+size bytes
4801 // parse packet size (ASN.1)
4806 uint32_t tmp_data_len
= 0;
4808 size
= mbuf
[3] & 0x7F;
4810 if(3 + size
< mbuf_len
)
4813 for (k
= 0; k
< size
; k
++)
4815 tmp_data_len
= (tmp_data_len
<< 8) | mbuf
[4 + k
];
4820 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16
") too short for opcode %08X", mbuf_len
, opcode
);
4826 if(tmp_data_len
> 0xFFFF)
4828 cs_log("Socket command too big: %d bytes", tmp_data_len
);
4829 (*data_len
) = 0xFFFF - 4 - size
;
4833 (*data_len
) = tmp_data_len
;
4838 (*data_len
) = mbuf
[3] & 0x7F;
4841 (*chunksize
) = 4 + size
+ (*data_len
);
4843 cs_log_dbg(D_DVBAPI
, "Got packet with opcode %08X and size %" PRIu16
, opcode
, (*chunksize
));
4845 else switch (opcode
)
4847 case DVBAPI_FILTER_DATA
: // min 9 bytes
4851 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16
") too short for DVBAPI_FILTER_DATA", mbuf_len
);
4857 (*data_len
) = b2i(2, mbuf
+ 7) & 0x0FFF;
4858 (*chunksize
) = 6 + 3 + (*data_len
);
4860 cs_log_dbg(D_DVBAPI
, "Got DVBAPI_FILTER_DATA packet with size %" PRIu16
, (*chunksize
));
4863 case DVBAPI_CLIENT_INFO
: // min 7 bytes
4867 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16
") too short for DVBAPI_CLIENT_INFO", mbuf_len
);
4873 (*data_len
) = mbuf
[6];
4874 (*chunksize
) = 6 + 1 + (*data_len
);
4876 cs_log_dbg(D_DVBAPI
, "Got DVBAPI_CLIENT_INFO packet with size %" PRIu16
, (*chunksize
));
4881 cs_log("Unknown socket command received: 0x%08X", opcode
);
4888 if((*chunksize
) < 1)
4893 if((*chunksize
) > 1)
4894 (*chunksize
) += msgid_size
;
4897 static 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
)
4900 if (*client_proto_version
>= 3) {
4901 if (mbuf
[0] != 0xa5) {
4902 cs_log("Error: network packet malformed! (no start)");
4905 msgid
= b2i(4, mbuf
+ 1);
4909 uint32_t opcode
= b2i(4, mbuf
); //get the client opcode (4 bytes)
4911 if((opcode
& 0xFFFFF000) == DVBAPI_AOT_CA
)
4913 switch(opcode
& 0xFFFFFF00)
4915 case DVBAPI_AOT_CA_PMT
:
4919 cs_log("Error: packet DVBAPI_AOT_CA_PMT is too short!");
4923 cs_log_dbg(D_DVBAPI
, "PMT Update on socket %d.", connfd
);
4924 cs_log_dump_dbg(D_DVBAPI
, mbuf
, chunksize
, "Parsing PMT object:");
4926 dvbapi_parse_capmt(mbuf
+ (chunksize
- data_len
), data_len
, connfd
, NULL
, 0, 0, *client_proto_version
, msgid
);
4929 case (DVBAPI_AOT_CA_STOP
& 0xFFFFFF00):
4931 // 9F 80 3f 04 83 02 00 <demux index>
4932 if(opcode
!= DVBAPI_AOT_CA_STOP
)
4934 cs_log_dbg(D_DVBAPI
, "dvbapi_handlesockmsg(): DVBAPI_AOT_CA opcode unknown: %08X", opcode
);
4941 cs_log("Error: packet DVBAPI_AOT_CA_STOP is too short!");
4946 if(cfg
.dvbapi_boxtype
== BOXTYPE_IPBOX
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
|| cfg
.dvbapi_listenport
)
4948 int32_t demux_index
= mbuf
[7];
4949 for(i
= 0; i
< MAX_DEMUX
; i
++)
4951 // 0xff demux_index is a wildcard => close all related demuxers
4952 if(demux_index
== 0xff)
4954 if(demux
[i
].socket_fd
== connfd
)
4956 dvbapi_stop_descrambling(i
, msgid
);
4959 else if (demux
[i
].demux_index
== demux_index
)
4961 dvbapi_stop_descrambling(i
, msgid
);
4965 if (cfg
.dvbapi_boxtype
== BOXTYPE_IPBOX
)
4967 // check do we have any demux running on this fd
4968 int16_t execlose
= 1;
4969 for(i
= 0; i
< MAX_DEMUX
; i
++)
4971 if(demux
[i
].socket_fd
== connfd
)
4979 int32_t ret
= close(connfd
);
4980 if(ret
< 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno
, strerror(errno
)); }
4986 if(cfg
.dvbapi_pmtmode
!= 6)
4988 int32_t ret
= close(connfd
);
4989 if(ret
< 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno
, strerror(errno
)); }
4996 cs_log_dbg(D_DVBAPI
, "dvbapi_handlesockmsg(): DVBAPI_AOT_CA opcode unknown: %08X", opcode
);
5001 if(cfg
.dvbapi_listenport
&& opcode
== DVBAPI_AOT_CA_STOP
)
5012 case DVBAPI_FILTER_DATA
:
5016 cs_log("Error: packet DVBAPI_FILTER_DATA is too short!");
5020 int32_t demux_id
= mbuf
[4];
5021 int32_t filter_num
= mbuf
[5];
5023 if(demux_id
< 0 || demux_id
>= MAX_DEMUX
)
5025 cs_log("dvbapi_handlesockmsg(): error - received invalid demux_id (%d)", demux_id
);
5029 if(filter_num
< 0 || filter_num
>= MAX_FILTER
)
5031 cs_log("dvbapi_handlesockmsg(): error - received invalid filter_num (%d)", filter_num
);
5035 dvbapi_process_input(demux_id
, filter_num
, mbuf
+ 6, data_len
+ 3, msgid
);
5038 case DVBAPI_CLIENT_INFO
:
5040 uint16_t client_proto
= b2i(2, mbuf
+ 4);
5042 NULLFREE(last_client_name
);
5044 if(cs_malloc(&last_client_name
, data_len
+ 1))
5046 memcpy(last_client_name
, &mbuf
[7], data_len
);
5047 last_client_name
[data_len
] = 0;
5048 cs_log("Client connected: '%s' (protocol version = %" PRIu16
")", last_client_name
, client_proto
);
5051 (*client_proto_version
) = client_proto
; //setting the global var according to the client
5052 last_client_proto_version
= client_proto
;
5054 // as a response we are sending our info to the client:
5055 dvbapi_net_send(DVBAPI_SERVER_INFO
, connfd
, msgid
, -1, -1, NULL
, NULL
, NULL
, client_proto
);
5060 cs_log_dbg(D_DVBAPI
, "dvbapi_handlesockmsg(): opcode unknown: %08X", opcode
);
5061 cs_log_dump(mbuf
, chunksize
, "Unknown command:");
5067 static bool dvbapi_handlesockdata(int32_t connfd
, uchar
* mbuf
, uint16_t mbuf_size
, uint16_t unhandled_len
,
5068 uint8_t* add_to_poll
, uint16_t* new_unhandled_len
, uint16_t* client_proto_version
)
5070 int32_t recv_result
;
5071 uint16_t chunksize
= 1, data_len
= 1;
5072 uint8_t packet_count
= 0;
5074 uint16_t missing_header_bytes
= dvbapi_get_nbof_missing_header_bytes(mbuf
, unhandled_len
);
5076 if(missing_header_bytes
)
5078 // read first few bytes so we know packet type and length
5079 cs_log_dbg(D_TRACE
, "%s to read %" PRIu16
" bytes from connection fd %d", (unhandled_len
== 0) ? "Trying":"Continue", missing_header_bytes
, connfd
);
5081 recv_result
= dvbapi_recv(connfd
, mbuf
+ unhandled_len
, mbuf_size
- unhandled_len
);
5084 (*new_unhandled_len
) = unhandled_len
;
5085 return (recv_result
!= -1);
5089 unhandled_len
+= recv_result
;
5091 if(unhandled_len
< dvbapi_get_nbof_missing_header_bytes(mbuf
, unhandled_len
))
5093 (*new_unhandled_len
) = unhandled_len
;
5101 // we got at least the first few bytes, detect packet type and length, then read the missing bytes
5102 dvbapi_get_packet_size(mbuf
, unhandled_len
, &chunksize
, &data_len
, *client_proto_version
);
5104 if(chunksize
> mbuf_size
)
5106 cs_log("***** WARNING: SOCKET DATA BUFFER OVERFLOW (%" PRIu16
" bytes), PLEASE REPORT! ****** ", chunksize
);
5107 (*new_unhandled_len
) = 0;
5111 if(unhandled_len
< chunksize
) // we are missing some bytes, try to read them
5113 cs_log_dbg(D_TRACE
, "Continue to read %d bytes from connection fd %d", chunksize
- unhandled_len
, connfd
);
5115 recv_result
= dvbapi_recv(connfd
, mbuf
+ unhandled_len
, mbuf_size
- unhandled_len
);
5118 (*new_unhandled_len
) = unhandled_len
;
5119 return (recv_result
!= -1);
5123 unhandled_len
+= recv_result
;
5125 if(unhandled_len
< chunksize
)
5127 (*new_unhandled_len
) = unhandled_len
;
5133 // we got at least one full packet, handle it, then return
5134 dvbapi_handlesockmsg(mbuf
, chunksize
, data_len
, add_to_poll
, connfd
, client_proto_version
);
5136 unhandled_len
-= chunksize
;
5138 if(unhandled_len
> 0)
5140 memmove(mbuf
, mbuf
+ chunksize
, unhandled_len
);
5145 } while(dvbapi_get_nbof_missing_header_bytes(mbuf
, unhandled_len
) == 0 && packet_count
< 7);
5147 (*new_unhandled_len
) = unhandled_len
;
5151 static void *dvbapi_main_local(void *cli
)
5154 struct s_client
*client
= (struct s_client
*) cli
;
5155 client
->thread
= pthread_self();
5156 SAFE_SETSPECIFIC(getclient
, cli
);
5158 dvbapi_client
= cli
;
5160 int32_t maxpfdsize
= (MAX_DEMUX
* maxfilter
) + MAX_DEMUX
+ 2;
5161 struct pollfd pfd2
[maxpfdsize
];
5162 struct timeb start
, end
; // start time poll, end time poll
5163 #define PMT_SERVER_SOCKET "/tmp/.listen.camd.socket"
5164 struct sockaddr_un saddr
;
5165 saddr
.sun_family
= AF_UNIX
;
5166 strncpy(saddr
.sun_path
, PMT_SERVER_SOCKET
, 107);
5167 saddr
.sun_path
[107] = '\0';
5169 int32_t rc
, pfdcount
, g
, connfd
, clilen
;
5170 int32_t ids
[maxpfdsize
], fdn
[maxpfdsize
], type
[maxpfdsize
];
5171 struct SOCKADDR servaddr
;
5173 static const uint16_t mbuf_size
= 2048;
5175 uint16_t unhandled_buf_len
[maxpfdsize
], unhandled_buf_used
[maxpfdsize
];
5176 uchar
*unhandled_buf
[maxpfdsize
];
5177 struct s_auth
*account
;
5179 uint16_t client_proto_version
[maxpfdsize
];
5181 if(!cs_malloc(&mbuf
, sizeof(uchar
)*mbuf_size
))
5186 for(i
= 0; i
< maxpfdsize
; i
++)
5188 unhandled_buf
[i
] = NULL
;
5189 unhandled_buf_len
[i
] = 0;
5190 unhandled_buf_used
[i
] = 0;
5192 client_proto_version
[i
] = 0;
5195 for(account
= cfg
.account
; account
!= NULL
; account
= account
->next
)
5197 if((ok
= is_dvbapi_usr(account
->usr
)))
5200 cs_auth_client(client
, ok
? account
: (struct s_auth
*)(-1), "dvbapi");
5202 memset(demux
, 0, sizeof(struct demux_s
) * MAX_DEMUX
);
5203 for(i
= 0; i
< MAX_DEMUX
; i
++)
5205 SAFE_MUTEX_INIT(&demux
[i
].answerlock
, NULL
);
5206 for(j
= 0; j
< ECM_PIDS
; j
++)
5208 for(l
= 0; l
< MAX_STREAM_INDICES
; l
++)
5210 demux
[i
].ECMpids
[j
].index
[l
] = INDEX_INVALID
;
5213 demux
[i
].pidindex
= -1;
5214 demux
[i
].curindex
= -1;
5217 memset(ca_fd
, 0, sizeof(ca_fd
));
5218 memset(unassoc_fd
, 0, sizeof(unassoc_fd
));
5220 dvbapi_read_priority();
5221 dvbapi_load_channel_cache();
5222 dvbapi_detect_api();
5224 if(selected_box
== -1 || selected_api
== -1)
5226 cs_log("ERROR: Could not detect DVBAPI version.");
5231 if(cfg
.dvbapi_pmtmode
== 1)
5232 { disable_pmt_files
= 1; }
5234 int32_t listenfd
= -1;
5235 if(cfg
.dvbapi_boxtype
!= BOXTYPE_IPBOX_PMT
&& cfg
.dvbapi_pmtmode
!= 2 && cfg
.dvbapi_pmtmode
!= 5 && cfg
.dvbapi_pmtmode
!= 6)
5237 if (!cfg
.dvbapi_listenport
)
5238 listenfd
= dvbapi_init_listenfd();
5240 listenfd
= dvbapi_net_init_listenfd();
5243 cs_log("ERROR: Could not init socket: (errno=%d: %s)", errno
, strerror(errno
));
5249 for(i
= 0; i
< MAX_DEMUX
; i
++) // init all demuxers!
5251 demux
[i
].pidindex
= -1;
5252 demux
[i
].curindex
= -1;
5255 if(cfg
.dvbapi_pmtmode
!= 4 && cfg
.dvbapi_pmtmode
!= 5 && cfg
.dvbapi_pmtmode
!= 6)
5257 struct sigaction signal_action
;
5258 signal_action
.sa_handler
= event_handler
;
5259 sigemptyset(&signal_action
.sa_mask
);
5260 signal_action
.sa_flags
= SA_RESTART
;
5261 sigaction(SIGRTMIN
+ 1, &signal_action
, NULL
);
5263 dir_fd
= open(TMPDIR
, O_RDONLY
);
5266 fcntl(dir_fd
, F_SETSIG
, SIGRTMIN
+ 1);
5267 fcntl(dir_fd
, F_NOTIFY
, DN_MODIFY
| DN_CREATE
| DN_DELETE
| DN_MULTISHOT
);
5268 event_handler(SIGRTMIN
+ 1);
5273 int32_t ret
= start_thread("dvbapi event", dvbapi_event_thread
, (void *) dvbapi_client
, NULL
, 1, 0);
5283 pfd2
[0].fd
= listenfd
;
5284 pfd2
[0].events
= (POLLIN
| POLLPRI
);
5288 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
5289 system("pzapit -rz");
5291 cs_ftime(&start
); // register start time
5294 if(pausecam
) // for dbox2, STAPI or PC in standby mode dont parse any ecm/emm or try to start next filter
5297 if(cfg
.dvbapi_pmtmode
== 6)
5301 cs_log("PMT6: Trying connect to enigma CA PMT listen socket...");
5303 if((listenfd
= socket(AF_UNIX
, SOCK_STREAM
, 0)) < 0)
5306 cs_log("socket error (errno=%d %s)", errno
, strerror(errno
));
5309 else if(connect(listenfd
, (struct sockaddr
*)&saddr
, sizeof(saddr
)) < 0)
5311 cs_log("socket connect error (errno=%d %s)", errno
, strerror(errno
));
5317 pfd2
[0].fd
= listenfd
;
5318 pfd2
[0].events
= (POLLIN
| POLLPRI
);
5320 cs_log("PMT6 CA PMT Server connected on fd %d!", listenfd
);
5323 if(listenfd
== -1) // not connected!
5326 continue; // start fresh connect attempt!
5330 pfdcount
= (listenfd
> -1) ? 1 : 0;
5332 for(i
= 0; i
< MAX_DEMUX
; i
++)
5334 // add client fd's which are not yet associated with the demux but needs to be polled for data
5335 if (unassoc_fd
[i
]) {
5336 pfd2
[pfdcount
].fd
= unassoc_fd
[i
];
5337 pfd2
[pfdcount
].events
= (POLLIN
| POLLPRI
);
5338 client_proto_version
[pfdcount
] = last_client_proto_version
;
5339 type
[pfdcount
++] = 1;
5342 if(demux
[i
].program_number
== 0) { continue; } // only evalutate demuxers that have channels assigned
5344 uint32_t ecmcounter
= 0, emmcounter
= 0;
5345 for(g
= 0; g
< maxfilter
; g
++)
5347 if(demux
[i
].demux_fd
[g
].fd
<= 0) continue; // deny obvious invalid fd!
5349 if(!cfg
.dvbapi_listenport
&& cfg
.dvbapi_boxtype
!= BOXTYPE_PC_NODMX
&& selected_api
!= STAPI
&& selected_api
!= COOLAPI
)
5351 pfd2
[pfdcount
].fd
= demux
[i
].demux_fd
[g
].fd
;
5352 pfd2
[pfdcount
].events
= (POLLIN
| POLLPRI
);
5355 type
[pfdcount
++] = 0;
5357 if(demux
[i
].demux_fd
[g
].type
== TYPE_ECM
) { ecmcounter
++; } // count ecm filters to see if demuxing is possible anyway
5358 if(demux
[i
].demux_fd
[g
].type
== TYPE_EMM
) { emmcounter
++; } // count emm filters also
5360 if(ecmcounter
!= demux
[i
].old_ecmfiltercount
|| emmcounter
!= demux
[i
].old_emmfiltercount
) // only produce log if something changed
5362 cs_log_dbg(D_DVBAPI
, "Demuxer %d has %d ecmpids, %d streampids, %d ecmfilters and %d of max %d emmfilters", i
, demux
[i
].ECMpidcount
,
5363 demux
[i
].STREAMpidcount
, ecmcounter
, emmcounter
, demux
[i
].max_emm_filter
);
5364 demux
[i
].old_ecmfiltercount
= ecmcounter
; // save new amount of ecmfilters
5365 demux
[i
].old_emmfiltercount
= emmcounter
; // save new amount of emmfilters
5368 // delayed emm start for non irdeto caids, start emm cat if not already done for this demuxer!
5373 int8_t do_emm_start
= (cfg
.dvbapi_au
> 0 && demux
[i
].emm_filter
== -1 && demux
[i
].EMMpidcount
== 0 && emmcounter
== 0);
5374 int8_t do_sdt_start
= (cfg
.dvbapi_read_sdt
&& demux
[i
].sdt_filter
== -1 && cfg
.dvbapi_boxtype
!= BOXTYPE_SAMYGO
);
5376 if(do_emm_start
|| do_sdt_start
)
5378 gone
= comp_timeb(&now
, &demux
[i
].emmstart
);
5383 cs_ftime(&demux
[i
].emmstart
); // trick to let emm fetching start after 30 seconds to speed up zapping
5384 dvbapi_start_filter(i
, demux
[i
].pidindex
, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM
); //CAT
5391 dvbapi_start_sdt_filter(i
);
5396 //early start for irdeto since they need emm before ecm (pmt emmstart = 1 if detected caid 0x06)
5397 int32_t emmstarted
= demux
[i
].emm_filter
;
5398 if(cfg
.dvbapi_au
&& demux
[i
].EMMpidcount
> 0) // check every time since share readers might give us new filters due to hexserial change
5400 if(!emmcounter
&& emmstarted
== -1)
5402 demux
[i
].emmstart
= now
;
5403 dvbapi_start_emm_filter(i
); // start emmfiltering if emmpids are found
5407 gone
= comp_timeb(&now
, &demux
[i
].emmstart
);
5410 demux
[i
].emmstart
= now
;
5411 dvbapi_start_emm_filter(i
); // start emmfiltering delayed if filters already were running
5412 rotate_emmfilter(i
); // rotate active emmfilters
5417 if(ecmcounter
== 0 && demux
[i
].ECMpidcount
> 0) // Restart decoding all caids we have ecmpids but no ecm filters!
5420 int32_t started
= 0;
5422 for(g
= 0; g
< demux
[i
].ECMpidcount
; g
++) // avoid race: not all pids are asked and checked out yet!
5424 if(demux
[i
].ECMpids
[g
].checked
== 0 && demux
[i
].ECMpids
[g
].status
>= 0) // check if prio run is done
5426 dvbapi_try_next_caid(i
, 0, 0); // not done, so start next prio pid
5431 if(started
) { continue; } // if started a filter proceed with next demuxer
5433 if(g
== demux
[i
].ECMpidcount
) // all usable pids (with prio) are tried, lets start over again without prio!
5435 for(g
= 0; g
< demux
[i
].ECMpidcount
; g
++) // avoid race: not all pids are asked and checked out yet!
5437 if(demux
[i
].ECMpids
[g
].checked
== 2 && demux
[i
].ECMpids
[g
].status
>= 0) // check if noprio run is done
5439 demux
[i
].ECMpids
[g
].irdeto_curindex
= 0xFE;
5440 demux
[i
].ECMpids
[g
].irdeto_maxindex
= 0;
5441 demux
[i
].ECMpids
[g
].irdeto_cycle
= 0xFE;
5442 demux
[i
].ECMpids
[g
].tries
= 0xFE;
5443 demux
[i
].ECMpids
[g
].table
= 0;
5444 demux
[i
].ECMpids
[g
].CHID
= 0x10000; // remove chid prio
5445 dvbapi_try_next_caid(i
, 2, 0); // not done, so start next no prio pid
5451 if(started
) { continue; } // if started a filter proceed with next demuxer
5453 if(g
== demux
[i
].ECMpidcount
) // all usable pids are tried, lets start over again!
5455 if(demux
[i
].decodingtries
== -1) // first redecoding attempt?
5457 cs_ftime(&demux
[i
].decstart
);
5458 for(g
= 0; g
< demux
[i
].ECMpidcount
; g
++) // reinit some used things from second run (without prio)
5460 demux
[i
].ECMpids
[g
].checked
= 0;
5461 demux
[i
].ECMpids
[g
].irdeto_curindex
= 0xFE;
5462 demux
[i
].ECMpids
[g
].irdeto_maxindex
= 0;
5463 demux
[i
].ECMpids
[g
].irdeto_cycle
= 0xFE;
5464 demux
[i
].ECMpids
[g
].table
= 0;
5465 demux
[i
].decodingtries
= 0;
5466 dvbapi_edit_channel_cache(i
, g
, 0); // remove this pid from channelcache since we had no founds on any ecmpid!
5469 uint8_t number_of_enabled_pids
= 0;
5470 demux
[i
].decodingtries
++;
5471 dvbapi_resort_ecmpids(i
);
5473 for(g
= 0; g
< demux
[i
].ECMpidcount
; g
++) // count number of enabled pids!
5475 if(demux
[i
].ECMpids
[g
].status
>= 0) number_of_enabled_pids
++;
5477 if(!number_of_enabled_pids
)
5479 if(demux
[i
].decodingtries
== 10)
5481 demux
[i
].decodingtries
= 0;
5482 cs_log("Demuxer %d no enabled matching ecmpids -> decoding is waiting for matching readers!",i
);
5487 cs_ftime(&demux
[i
].decend
);
5488 demux
[i
].decodingtries
= -1; // reset to first run again!
5489 gone
= comp_timeb(&demux
[i
].decend
, &demux
[i
].decstart
);
5490 cs_log("Demuxer %d restarting decodingrequests after %"PRId64
" ms with %d enabled and %d disabled ecmpids!", i
, gone
, number_of_enabled_pids
,
5491 (demux
[i
].ECMpidcount
-number_of_enabled_pids
));
5492 dvbapi_try_next_caid(i
, 0, 0);
5497 if(demux
[i
].socket_fd
> 0 && cfg
.dvbapi_pmtmode
!= 6)
5500 for(j
= 0; j
< pfdcount
; j
++)
5502 if(pfd2
[j
].fd
== demux
[i
].socket_fd
)
5508 if(rc
== 1) { continue; }
5510 pfd2
[pfdcount
].fd
= demux
[i
].socket_fd
;
5511 pfd2
[pfdcount
].events
= (POLLIN
| POLLPRI
);
5513 type
[pfdcount
++] = 1;
5518 while(!(listenfd
== -1 && cfg
.dvbapi_pmtmode
== 6))
5520 rc
= poll(pfd2
, pfdcount
, 500);
5521 if(rc
< 0) // error occured while polling for fd's with fresh data
5523 if(errno
== EINTR
|| errno
== EAGAIN
) // try again in case of interrupt
5527 cs_log("ERROR: error on poll of %d fd's (errno=%d %s)", pfdcount
, errno
, strerror(errno
));
5538 cs_ftime(&end
); // register end time
5539 int64_t timeout
= comp_timeb(&end
, &start
);
5541 cs_log("*** WARNING: BAD TIME AFFECTING WHOLE OSCAM ECM HANDLING ****");
5543 cs_log_dbg(D_TRACE
, "New events occurred on %d of %d handlers after %"PRId64
" ms inactivity", rc
, pfdcount
, timeout
);
5544 cs_ftime(&start
); // register new start time for next poll
5547 for(i
= 0; i
< pfdcount
&& rc
> 0; i
++)
5549 if(pfd2
[i
].revents
== 0) { continue; } // skip sockets with no changes
5550 rc
--; //event handled!
5551 cs_log_dbg(D_TRACE
, "Now handling fd %d that reported event %d", pfd2
[i
].fd
, pfd2
[i
].revents
);
5553 if(pfd2
[i
].revents
& (POLLHUP
| POLLNVAL
| POLLERR
))
5557 for(j
= 0; j
< MAX_DEMUX
; j
++)
5559 if(demux
[j
].socket_fd
== pfd2
[i
].fd
) // if listenfd closes stop all assigned decoding!
5561 dvbapi_stop_descrambling(j
, 0);
5564 // remove from unassoc_fd when necessary
5565 if (unassoc_fd
[j
] == pfd2
[i
].fd
)
5570 int32_t ret
= close(pfd2
[i
].fd
);
5571 if(ret
< 0 && errno
!= 9) { cs_log("ERROR: Could not close demuxer socket fd (errno=%d %s)", errno
, strerror(errno
)); }
5572 if(pfd2
[i
].fd
== listenfd
&& cfg
.dvbapi_pmtmode
== 6)
5577 cs_log_dbg(D_DVBAPI
, "Socket %d reported hard connection close", pfd2
[i
].fd
);
5581 int32_t demux_index
= ids
[i
];
5584 if(cfg
.dvbapi_boxtype
!= BOXTYPE_SAMYGO
)
5586 dvbapi_stop_filternum(demux_index
, n
, 0); // stop filter since its giving errors and wont return anything good.
5592 struct dmx_sct_filter_params sFP
;
5594 cs_log_dbg(D_DVBAPI
, "re-opening connection to demux socket");
5595 close(demux
[demux_index
].demux_fd
[n
].fd
);
5596 demux
[demux_index
].demux_fd
[n
].fd
= -1;
5598 ret
= dvbapi_open_device(0, demux
[demux_index
].demux_index
, demux
[demux_index
].adapter_index
);
5601 demux
[demux_index
].demux_fd
[n
].fd
= ret
;
5603 pid
= demux
[demux_index
].curindex
;
5605 memset(filter
, 0, 32);
5606 memset(&sFP
, 0, sizeof(sFP
));
5611 sFP
.pid
= demux
[demux_index
].ECMpids
[pid
].ECM_PID
;
5613 sFP
.flags
= DMX_IMMEDIATE_START
;
5614 memcpy(sFP
.filter
.filter
, filter
, 16);
5615 memcpy(sFP
.filter
.mask
, filter
+ 16, 16);
5616 ret
= dvbapi_ioctl(demux
[demux_index
].demux_fd
[n
].fd
, DMX_SET_FILTER
, &sFP
);
5620 dvbapi_stop_filternum(demux_index
, n
, 0); // stop filter since its giving errors and wont return anything good.
5623 continue; // continue with other events
5626 if(pfd2
[i
].revents
& (POLLIN
| POLLPRI
))
5630 connfd
= -1; // initially no socket to read from
5631 uint8_t add_to_poll
= 0; // we may need to additionally poll this socket when no PMT data comes in
5633 if (pfd2
[i
].fd
== listenfd
)
5635 if (cfg
.dvbapi_pmtmode
== 6) {
5637 disable_pmt_files
= 1;
5639 clilen
= sizeof(servaddr
);
5640 connfd
= accept(listenfd
, (struct sockaddr
*)&servaddr
, (socklen_t
*)&clilen
);
5641 cs_log_dbg(D_DVBAPI
, "new socket connection fd: %d", connfd
);
5642 if (cfg
.dvbapi_listenport
)
5645 client
->ip
= SIN_GET_ADDR(servaddr
);
5646 client
->port
= ntohs(SIN_GET_PORT(servaddr
));
5650 if(cfg
.dvbapi_pmtmode
== 3 || cfg
.dvbapi_pmtmode
== 0) { disable_pmt_files
= 1; }
5653 cs_log_dbg(D_DVBAPI
, "accept() returns error on fd event %d (errno=%d %s)", pfd2
[i
].revents
, errno
, strerror(errno
));
5658 connfd
= pfd2
[i
].fd
;
5661 //reading and completing data from socket
5664 if(unhandled_buf_used
[i
])
5666 memcpy(mbuf
, unhandled_buf
[i
], unhandled_buf_used
[i
]);
5669 if(!dvbapi_handlesockdata(connfd
, mbuf
, mbuf_size
, unhandled_buf_used
[i
], &add_to_poll
, &unhandled_buf_used
[i
], &client_proto_version
[i
]))
5671 unhandled_buf_used
[i
] = 0;
5673 //client disconnects, stop all assigned decoding
5674 cs_log_dbg(D_DVBAPI
, "Socket %d reported connection close", connfd
);
5675 int active_conn
= 0; //other active connections counter
5678 for (j
= 0; j
< MAX_DEMUX
; j
++)
5680 if (demux
[j
].socket_fd
== connfd
)
5682 dvbapi_stop_descrambling(j
, 0);
5684 else if (demux
[j
].socket_fd
)
5689 // remove from unassoc_fd when necessary
5690 if (unassoc_fd
[j
] == connfd
)
5699 if (!active_conn
&& (cfg
.dvbapi_listenport
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)) //last connection closed
5701 if (cfg
.dvbapi_listenport
)
5704 client
->ip
= get_null_ip();
5712 if(unhandled_buf_used
[i
])
5714 if(unhandled_buf_used
[i
] > unhandled_buf_len
[i
])
5716 NULLFREE(unhandled_buf
[i
]);
5718 unhandled_buf_len
[i
] = unhandled_buf_used
[i
] < 128 ? 128 : unhandled_buf_used
[i
];
5720 if(!cs_malloc(&unhandled_buf
[i
], sizeof(uchar
)*unhandled_buf_len
[i
]))
5722 unhandled_buf_len
[i
] = 0;
5723 unhandled_buf_used
[i
] = 0;
5728 memcpy(unhandled_buf
[i
], mbuf
, unhandled_buf_used
[i
]);
5731 // if the connection is new and we read no PMT data, then add it to the poll,
5732 // otherwise this socket will not be checked with poll when data arives
5733 // because fd it is not yet assigned with the demux
5735 for (j
= 0; j
< MAX_DEMUX
; j
++) {
5736 if (!unassoc_fd
[j
]) {
5737 unassoc_fd
[j
] = connfd
;
5746 int32_t demux_index
= ids
[i
];
5749 if((int)demux
[demux_index
].demux_fd
[n
].fd
!= pfd2
[i
].fd
) { continue; } // filter already killed, no need to process this data!
5751 len
= dvbapi_read_device(pfd2
[i
].fd
, mbuf
, mbuf_size
);
5752 if(len
< 0) // serious filterdata read error
5754 dvbapi_stop_filternum(demux_index
, n
, 0); // stop filter since its giving errors and wont return anything good.
5755 maxfilter
--; // lower maxfilters to avoid this with new filter setups!
5758 if(!len
) // receiver internal filterbuffer overflow
5760 memset(mbuf
, 0, mbuf_size
);
5763 dvbapi_process_input(demux_index
, n
, mbuf
, len
, 0);
5765 continue; // continue with other events!
5770 for(j
= 0; j
< maxpfdsize
; j
++)
5772 NULLFREE(unhandled_buf
[j
]);
5778 void 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
, uint32_t msgid
)
5782 unsigned char nullcw
[8];
5783 memset(nullcw
, 0, 8);
5784 ca_descr_t ca_descr
;
5785 ca_descr_mode_t ca_descr_mode
;
5787 memset(&ca_descr
, 0, sizeof(ca_descr
));
5788 memset(&ca_descr_mode
, 0, sizeof(ca_descr_mode_t
));
5790 if(memcmp(demux
[demux_id
].lastcw
[0], nullcw
, 8) == 0
5791 && memcmp(demux
[demux_id
].lastcw
[1], nullcw
, 8) == 0)
5792 { cwEmpty
= 1; } // to make sure that both cws get written on constantcw
5795 for(n
= 0; n
< 2; n
++)
5799 cs_hexdump(0, demux
[demux_id
].lastcw
[n
], 8, lastcw
, sizeof(lastcw
));
5800 cs_hexdump(0, cw
+ (n
* 8), 8, newcw
, sizeof(newcw
));
5802 // check if already delivered and new cw part is valid but dont check for nullcw on Biss
5803 if((memcmp(cw
+ (n
* 8), demux
[demux_id
].lastcw
[n
], 8) != 0 || cwEmpty
|| stream_id
>1)
5804 && (memcmp(cw
+ (n
* 8), nullcw
, 8) != 0 || demux
[demux_id
].ECMpids
[pid
].CAID
== 0x2600))
5806 ca_index_t idx
= dvbapi_ca_setpid(demux_id
, pid
, stream_id
, (algo
== CA_ALGO_DES
), msgid
); // prepare ca
5807 if (idx
== INDEX_INVALID
) return; // return on no index!
5809 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
5810 ca_descr_mode
.cipher_mode
= cipher_mode
;
5811 ca_descr
.index
= idx
;
5812 ca_descr
.parity
= n
;
5813 memcpy(demux
[demux_id
].lastcw
[n
], cw
+ (n
* 8), 8);
5814 memcpy(ca_descr
.cw
, cw
+ (n
* 8), 8);
5815 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
);
5816 coolapi_write_cw(demux
[demux_id
].ca_mask
, demux
[demux_id
].STREAMpids
, demux
[demux_id
].STREAMpidcount
, &ca_descr
);
5818 int32_t i
, j
, write_cw
= 0;
5819 ca_index_t usedidx
, lastidx
;
5821 for(i
= 0; i
< MAX_DEMUX
; i
++)
5823 if(!(demux
[demux_id
].ca_mask
& (1 << i
))) continue; // ca not in use by this demuxer!
5825 lastidx
= INDEX_INVALID
;
5827 for(j
= 0; j
< demux
[demux_id
].STREAMpidcount
; j
++)
5830 if(!demux
[demux_id
].ECMpids
[pid
].streams
|| ((demux
[demux_id
].ECMpids
[pid
].streams
& (1 << j
)) == (uint
) (1 << j
)))
5832 usedidx
= is_ca_used(i
, demux
[demux_id
].STREAMpids
[j
]);
5833 if(usedidx
!= INDEX_INVALID
)
5837 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
]);
5838 continue; // if not used for descrambling -> skip!
5842 if(usedidx
== lastidx
)
5844 cs_log_dbg(D_DVBAPI
,"Demuxer %d ca%d is using index %d for streampid %04X -> skip, %s part of cw already written!",
5845 demux_id
, i
, usedidx
, demux
[demux_id
].STREAMpids
[j
], (n
== 1 ? "even" : "odd"));
5848 cs_log_dbg(D_DVBAPI
,"Demuxer %d ca%d is using index %d for streampid %04X -> write %s part of cw!",
5849 demux_id
, i
, usedidx
, demux
[demux_id
].STREAMpids
[j
], (n
== 1 ? "even" : "odd"));
5854 if(!write_cw
) { continue; } // no need to write the cw since this ca isnt using it!
5857 ca_descr
.index
= usedidx
;
5858 ca_descr
.parity
= n
;
5859 memcpy(demux
[demux_id
].lastcw
[n
], cw
+ (n
* 8), 8);
5860 memcpy(ca_descr
.cw
, cw
+ (n
* 8), 8);
5861 cs_log_dbg(D_DVBAPI
, "Demuxer %d writing %s part (%s) of controlword, replacing expired (%s)", demux_id
, (n
== 1 ? "even" : "odd"), newcw
, lastcw
);
5862 cs_log_dbg(D_DVBAPI
, "Demuxer %d write cw%d index: %d (ca%d)", demux_id
, n
, ca_descr
.index
, i
);
5864 if(cfg
.dvbapi_extended_cw_api
== 1)
5866 ca_descr_mode
.index
= usedidx
;
5867 ca_descr_mode
.algo
= algo
;
5868 ca_descr_mode
.cipher_mode
= cipher_mode
;
5870 if(cfg
.dvbapi_boxtype
== BOXTYPE_PC
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)
5871 dvbapi_net_send(DVBAPI_CA_SET_DESCR_MODE
, demux
[demux_id
].socket_fd
, msgid
, demux_id
, -1 /*unused*/, (unsigned char *) &ca_descr_mode
, NULL
, NULL
, demux
[demux_id
].client_proto_version
);
5876 ca_fd
[i
] = dvbapi_open_device(1, i
, demux
[demux_id
].adapter_index
);
5877 if(ca_fd
[i
] <= 0) { continue; }
5879 if (dvbapi_ioctl(ca_fd
[i
], CA_SET_DESCR_MODE
, &ca_descr_mode
) < 0)
5881 cs_log("ERROR: ioctl(CA_SET_DESCR_MODE): %s", strerror(errno
));
5886 if(cfg
.dvbapi_boxtype
== BOXTYPE_PC
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)
5887 dvbapi_net_send(DVBAPI_CA_SET_DESCR
, demux
[demux_id
].socket_fd
, msgid
, demux_id
, -1 /*unused*/, (unsigned char *) &ca_descr
, NULL
, NULL
, demux
[demux_id
].client_proto_version
);
5892 ca_fd
[i
] = dvbapi_open_device(1, i
, demux
[demux_id
].adapter_index
);
5893 if(ca_fd
[i
] <= 0) { continue; }
5895 if (dvbapi_ioctl(ca_fd
[i
], CA_SET_DESCR
, &ca_descr
) < 0)
5897 cs_log("ERROR: ioctl(CA_SET_DESCR): %s", strerror(errno
));
5908 void delayer(ECM_REQUEST
*er
, uint32_t delay
)
5910 if(delay
<= 0) { return; }
5914 int64_t gone
= comp_timeb(&tpe
, &er
->tps
);
5917 cs_log_dbg(D_DVBAPI
, "delayer: gone=%"PRId64
" ms, cfg=%d ms -> delay=%"PRId64
" ms", gone
, delay
, delay
- gone
);
5918 cs_sleepms(delay
- gone
);
5922 void dvbapi_send_dcw(struct s_client
*client
, ECM_REQUEST
*er
)
5924 int32_t i
, j
, k
, handled
= 0;
5926 for(i
= 0; i
< MAX_DEMUX
; i
++)
5928 uint32_t nocw_write
= 0; // 0 = write cw, 1 = dont write cw to hardware demuxer
5929 if(demux
[i
].program_number
== 0) { continue; } // ignore empty demuxers
5930 if(demux
[i
].program_number
!= er
->srvid
) { continue; } // skip ecm response for other srvid
5931 if(demux
[i
].adapter_index
!= er
->adapter_index
) { continue; } // skip ecm recponse for different adapter
5934 if(strcmp(dev_list
[demux
[i
].dev_index
].name
, er
->dev_name
) != 0) { continue; } // skip request if PTI device doesn't match request
5937 demux
[i
].rdr
= er
->selected_reader
;
5938 for(j
= 0; j
< demux
[i
].ECMpidcount
; j
++) // check for matching ecmpid
5940 if((demux
[i
].ECMpids
[j
].CAID
== er
->caid
|| demux
[i
].ECMpids
[j
].CAID
== er
->ocaid
)
5941 && demux
[i
].ECMpids
[j
].ECM_PID
== er
->pid
5942 && demux
[i
].ECMpids
[j
].PROVID
== er
->prid
5943 && demux
[i
].ECMpids
[j
].VPID
== er
->vpid
)
5946 if(j
== demux
[i
].ECMpidcount
) { continue; } // ecm response srvid ok but no matching ecmpid, perhaps this for other demuxer
5948 cs_log_dbg(D_DVBAPI
, "Demuxer %d %scontrolword received for PID %d CAID %04X PROVID %06X ECMPID %04X CHID %04X VPID %04X", i
,
5949 (er
->rc
>= E_NOTFOUND
? "no " : ""), j
, er
->caid
, er
->prid
, er
->pid
, er
->chid
, er
->vpid
);
5951 uint32_t status
= dvbapi_check_ecm_delayed_delivery(i
, er
);
5953 uint32_t comparecw0
= 0, comparecw1
= 0;
5955 cs_hexdump(0, er
->ecmd5
, 16, ecmd5
, sizeof(ecmd5
));
5957 if(status
== 1 && er
->rc
) // wrong ecmhash
5959 cs_log_dbg(D_DVBAPI
, "Demuxer %d not interested in response ecmhash %s (requested different one)", i
, ecmd5
);
5962 if(status
== 2) // no filter
5964 cs_log_dbg(D_DVBAPI
, "Demuxer %d not interested in response ecmhash %s (filter already killed)", i
, ecmd5
);
5967 if(status
== 5) // empty cw
5969 cs_log_dbg(D_DVBAPI
, "Demuxer %d not interested in response ecmhash %s (delivered cw is empty!)", i
, ecmd5
);
5971 if(er
->rc
< E_NOTFOUND
) { er
->rc
= E_NOTFOUND
; }
5974 // 0=matching ecm hash, 2=no filter, 3=table reset, 4=cache-ex response
5975 // Dont check for biss since it is using constant cw and cw can even be all zeros
5976 if((status
== 0 || status
== 3 || status
== 4) && er
->rc
< E_NOTFOUND
&& er
->caid
!=0x2600)
5978 if(memcmp(er
->cw
, demux
[i
].lastcw
[0], 8) == 0 && memcmp(er
->cw
+ 8, demux
[i
].lastcw
[1], 8) == 0) // check for matching controlword
5982 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
5986 if(comparecw0
== 1 || comparecw1
== 1)
5988 cs_log_dbg(D_DVBAPI
, "Demuxer %d duplicate controlword ecm response hash %s (duplicate controlword!)", i
, ecmd5
);
5993 if(status
== 3) // table reset
5995 cs_log_dbg(D_DVBAPI
, "Demuxer %d luckyshot new controlword ecm response hash %s (ecm table reset)", i
, ecmd5
);
5998 if(status
== 4) // no check on cache-ex responses!
6000 cs_log_dbg(D_DVBAPI
, "Demuxer %d new controlword from cache-ex reader (no ecmhash check possible)", i
);
6003 handled
= 1; // mark this ecm response as handled
6004 if(er
->rc
< E_NOTFOUND
&& cfg
.dvbapi_requestmode
== 0 && (demux
[i
].pidindex
== -1) && er
->caid
!= 0)
6006 demux
[i
].ECMpids
[j
].tries
= 0xFE; // reset timeout retry flag
6007 demux
[i
].ECMpids
[j
].irdeto_cycle
= 0xFE; // reset irdetocycle
6008 demux
[i
].pidindex
= j
; // set current index as *the* pid to descramble
6009 demux
[i
].ECMpids
[j
].checked
= 4;
6010 cs_log_dbg(D_DVBAPI
, "Demuxer %d descrambling PID %d CAID %04X PROVID %06X ECMPID %04X CHID %02X VPID %04X",
6011 i
, demux
[i
].pidindex
, er
->caid
, er
->prid
, er
->pid
, er
->chid
, er
->vpid
);
6014 if(er
->rc
< E_NOTFOUND
&& cfg
.dvbapi_requestmode
== 1 && er
->caid
!= 0) // FOUND
6016 SAFE_MUTEX_LOCK(&demux
[i
].answerlock
); // only process one ecm answer
6018 if(demux
[i
].ECMpids
[j
].checked
!= 4)
6021 int32_t t
, o
, ecmcounter
= 0;
6022 int32_t oldpidindex
= demux
[i
].pidindex
;
6023 demux
[i
].pidindex
= j
; // set current ecmpid as the new pid to descramble
6024 if(oldpidindex
!= -1)
6026 for(k
= 0; k
< MAX_STREAM_INDICES
; k
++)
6028 demux
[i
].ECMpids
[j
].index
[k
] = demux
[i
].ECMpids
[oldpidindex
].index
[k
]; // swap index with lower status pid that was descrambling
6029 demux
[i
].ECMpids
[j
].useMultipleIndices
= demux
[i
].ECMpids
[oldpidindex
].useMultipleIndices
;
6033 for(t
= 0; t
< demux
[i
].ECMpidcount
; t
++) //check this pid with controlword FOUND for higher status:
6035 if(t
!= j
&& demux
[i
].ECMpids
[j
].status
>= demux
[i
].ECMpids
[t
].status
)
6037 for(o
= 0; o
< maxfilter
; o
++) // check if ecmfilter is in use & stop all ecmfilters of lower status pids
6039 if(demux
[i
].demux_fd
[o
].fd
> 0 && demux
[i
].demux_fd
[o
].type
== TYPE_ECM
&& (demux
[i
].demux_fd
[o
].pidindex
== t
))
6041 dvbapi_stop_filternum(i
, o
, er
->msgid
); // ecmfilter belongs to lower status pid -> kill!
6044 dvbapi_edit_channel_cache(i
, t
, 0); // remove lowerstatus pid from channelcache
6045 demux
[i
].ECMpids
[t
].checked
= 4; // mark index t as low status
6050 for(o
= 0; o
< maxfilter
; o
++) if(demux
[i
].demux_fd
[o
].type
== TYPE_ECM
) { ecmcounter
++; } // count all ecmfilters
6052 demux
[i
].ECMpids
[j
].tries
= 0xFE; // reset timeout retry flag
6053 demux
[i
].ECMpids
[j
].irdeto_cycle
= 0xFE; // reset irdetocycle
6055 if(ecmcounter
== 1) // if total found running ecmfilters is 1 -> we found the "best" pid
6057 dvbapi_edit_channel_cache(i
, j
, 1);
6058 demux
[i
].ECMpids
[j
].checked
= 4; // mark best pid last ;)
6061 cs_log_dbg(D_DVBAPI
, "Demuxer %d descrambling PID %d CAID %04X PROVID %06X ECMPID %04X CHID %02X VPID %04X",
6062 i
, demux
[i
].pidindex
, er
->caid
, er
->prid
, er
->pid
, er
->chid
, er
->vpid
);
6064 SAFE_MUTEX_UNLOCK(&demux
[i
].answerlock
); // and release it!
6067 if(er
->rc
>= E_NOTFOUND
) // not found on requestmode 0 + 1
6069 if(er
->rc
== E_SLEEPING
)
6071 dvbapi_stop_descrambling(i
, er
->msgid
);
6075 struct s_dvbapi_priority
*forceentry
= dvbapi_check_prio_match(i
, j
, 'p');
6077 if(forceentry
&& forceentry
->force
) // forced pid? keep trying the forced ecmpid!
6079 if(!caid_is_irdeto(er
->caid
) || forceentry
->chid
< 0x10000) //all cas or irdeto cas with forced prio chid
6081 demux
[i
].ECMpids
[j
].table
= 0;
6082 dvbapi_set_section_filter(i
, er
, -1);
6085 else // irdeto cas without chid prio forced
6087 if(demux
[i
].ECMpids
[j
].irdeto_curindex
== 0xFE) { demux
[i
].ECMpids
[j
].irdeto_curindex
= 0x00; } // init irdeto current index to first one
6088 if(!(demux
[i
].ECMpids
[j
].irdeto_curindex
+ 1 > demux
[i
].ECMpids
[j
].irdeto_maxindex
)) // check for last / max chid
6090 cs_log_dbg(D_DVBAPI
, "Demuxer %d trying next irdeto chid of FORCED PID %d CAID %04X PROVID %06X ECMPID %04X", i
,
6091 j
, er
->caid
, er
->prid
, er
->pid
);
6092 demux
[i
].ECMpids
[j
].irdeto_curindex
++; // irdeto index one up
6093 demux
[i
].ECMpids
[j
].table
= 0;
6094 dvbapi_set_section_filter(i
, er
, -1);
6100 // in case of timeout or fatal LB event give this pid another try but no more than 1 try
6101 if((er
->rc
== E_TIMEOUT
|| (er
->rcEx
&& er
->rcEx
<= E2_CCCAM_NOCARD
)) && demux
[i
].ECMpids
[j
].tries
== 0xFE)
6103 demux
[i
].ECMpids
[j
].tries
-=0x07;
6104 demux
[i
].ECMpids
[j
].table
= 0;
6105 dvbapi_set_section_filter(i
, er
, -1);
6108 else // all not found responses exception: first timeout response and first fatal loadbalancer response
6110 demux
[i
].ECMpids
[j
].CHID
= 0x10000; // get rid of this prio chid since it failed!
6111 demux
[i
].ECMpids
[j
].tries
= 0xFE; // reset timeout retry
6114 if(caid_is_irdeto(er
->caid
))
6116 if(demux
[i
].ECMpids
[j
].irdeto_curindex
== 0xFE) { demux
[i
].ECMpids
[j
].irdeto_curindex
= 0x00; } // init irdeto current index to first one
6117 if(!(demux
[i
].ECMpids
[j
].irdeto_curindex
+ 1 > demux
[i
].ECMpids
[j
].irdeto_maxindex
)) // check for last / max chid
6119 cs_log_dbg(D_DVBAPI
, "Demuxer %d trying next irdeto chid of PID %d CAID %04X PROVID %06X ECMPID %04X VPID %04X", i
,
6120 j
, er
->caid
, er
->prid
, er
->pid
, er
->vpid
);
6121 demux
[i
].ECMpids
[j
].irdeto_curindex
++; // irdeto index one up
6122 demux
[i
].ECMpids
[j
].table
= 0;
6123 dvbapi_set_section_filter(i
, er
, -1);
6128 dvbapi_edit_channel_cache(i
, j
, 0); // remove this pid from channelcache
6129 if(demux
[i
].pidindex
== j
)
6131 demux
[i
].pidindex
= -1; // current pid delivered a notfound so this pid isnt being used to descramble any longer-> clear pidindex
6133 demux
[i
].ECMpids
[j
].irdeto_maxindex
= 0;
6134 demux
[i
].ECMpids
[j
].irdeto_curindex
= 0xFE;
6135 demux
[i
].ECMpids
[j
].tries
= 0xFE; // reset timeout retry flag
6136 demux
[i
].ECMpids
[j
].irdeto_cycle
= 0xFE; // reset irdetocycle
6137 demux
[i
].ECMpids
[j
].table
= 0;
6138 demux
[i
].ECMpids
[j
].checked
= 4; // flag ecmpid as checked
6139 demux
[i
].ECMpids
[j
].status
= -1; // flag ecmpid as unusable
6140 int32_t found
= 1; // setup for first run
6141 int32_t filternum
= -1;
6143 while(found
> 0) // disable all ecm + emm filters for this notfound
6146 filternum
= dvbapi_get_filternum(i
, er
, TYPE_ECM
); // get ecm filternumber
6147 if(filternum
> -1) // in case valid filter found
6149 int32_t fd
= demux
[i
].demux_fd
[filternum
].fd
;
6150 if(fd
> 0) // in case valid fd
6152 dvbapi_stop_filternum(i
, filternum
, er
->msgid
); // stop ecmfilter
6156 if(caid_is_irdeto(er
->caid
)) // in case irdeto cas stop old emm filters
6158 filternum
= dvbapi_get_filternum(i
, er
, TYPE_EMM
); // get emm filternumber
6159 if(filternum
> -1) // in case valid filter found
6161 int32_t fd
= demux
[i
].demux_fd
[filternum
].fd
;
6162 if(fd
> 0) // in case valid fd
6164 dvbapi_stop_filternum(i
, filternum
, er
->msgid
); // stop emmfilter
6175 // below this should be only run in case of ecm answer is found
6177 uint32_t chid
= get_subid(er
); // derive current chid in case of irdeto, or a unique part of ecm on other cas systems
6178 demux
[i
].ECMpids
[j
].CHID
= (chid
!= 0 ? chid
: 0x10000); // if not zero apply, otherwise use no chid value 0x10000
6179 dvbapi_edit_channel_cache(i
, j
, 1); // do it here to here after the right CHID is registered
6181 //dvbapi_set_section_filter(i, er); is not needed anymore (unsure)
6182 demux
[i
].ECMpids
[j
].tries
= 0xFE; // reset timeout retry flag
6183 demux
[i
].ECMpids
[j
].irdeto_cycle
= 0xFE; // reset irdeto cycle
6185 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!
6187 struct s_dvbapi_priority
*delayentry
= dvbapi_check_prio_match(i
, demux
[i
].pidindex
, 'd');
6192 if(delayentry
->delay
< 1000)
6194 delay
= delayentry
->delay
;
6195 cs_log_dbg(D_DVBAPI
, "specific delay: write cw %d ms after ecmrequest", delay
);
6198 else if (cfg
.dvbapi_delayer
> 0)
6200 delay
= cfg
.dvbapi_delayer
;
6201 cs_log_dbg(D_DVBAPI
, "generic delay: write cw %d ms after ecmrequest", delay
);
6206 switch(selected_api
)
6208 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
6210 stapi_write_cw(i
, er
->cw
, demux
[i
].STREAMpids
, demux
[i
].STREAMpidcount
, demux
[i
].pmt_file
);
6215 #ifdef WITH_EXTENDED_CW
6217 if(er
->cw_ex
.mode
!= demux
[i
].ECMpids
[j
].useMultipleIndices
)
6220 for(k
= 0; k
< demux
[i
].STREAMpidcount
; k
++)
6222 idx
= demux
[i
].ECMpids
[j
].useMultipleIndices
? demux
[i
].ECMpids
[j
].index
[k
] : demux
[i
].ECMpids
[j
].index
[0];
6223 dvbapi_set_pid(i
, k
, idx
, false, false, er
->msgid
); // disable streampid
6226 for(k
= 0; k
< MAX_STREAM_INDICES
; k
++)
6228 demux
[i
].ECMpids
[j
].index
[k
] = INDEX_INVALID
;
6232 if(er
->cw_ex
.mode
== CW_MODE_MULTIPLE_CW
)
6234 int32_t key_pos_a
= 0;
6235 uint8_t *cw
, stream_type
;
6237 demux
[i
].ECMpids
[j
].useMultipleIndices
= 1;
6239 for(k
= 0; k
< demux
[i
].STREAMpidcount
; k
++)
6241 stream_type
= demux
[i
].STREAMpidsType
[k
];
6244 if(stream_type
== 0x01 || stream_type
== 0x02 || stream_type
== 0x10 || stream_type
== 0x1B
6245 || stream_type
== 0x24 || stream_type
== 0x42 || stream_type
== 0x80 || stream_type
== 0xD1
6246 || stream_type
== 0xEA)
6251 else if(stream_type
== 0x03 || stream_type
== 0x04 || stream_type
== 0x06 || stream_type
== 0x0F
6252 || stream_type
== 0x11 || stream_type
== 0x81 || (stream_type
>= 0x83 && stream_type
<= 0x87)
6253 || stream_type
== 0x8A)
6255 cw
= er
->cw_ex
.audio
[key_pos_a
];
6265 cw
= er
->cw_ex
.data
;
6268 dvbapi_write_cw(i
, cw
, j
, k
, er
->cw_ex
.algo
, er
->cw_ex
.algo_mode
, er
->msgid
);
6273 demux
[i
].ECMpids
[j
].useMultipleIndices
= 0;
6274 dvbapi_write_cw(i
, er
->cw
, j
, 0, er
->cw_ex
.algo
, er
->cw_ex
.algo_mode
, er
->msgid
);
6277 cfg
.dvbapi_extended_cw_api
= 0; // in CSA mode extended_cw_api should be always 0 regardless what user selected!
6278 dvbapi_write_cw(i
, er
->cw
, j
, 0, CA_ALGO_DVBCSA
, CA_MODE_ECB
, er
->msgid
);
6285 client
->last
= time((time_t *)0); // ********* TO BE FIXED LATER ON ******
6287 if ((cfg
.dvbapi_listenport
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
) && demux
[i
].client_proto_version
>= 2)
6288 { dvbapi_net_send(DVBAPI_ECM_INFO
, demux
[i
].socket_fd
, 0, i
, 0, NULL
, client
, er
, demux
[i
].client_proto_version
); }
6290 else if (!cfg
.dvbapi_listenport
&& cfg
.dvbapi_boxtype
!= BOXTYPE_PC_NODMX
)
6292 if(cfg
.dvbapi_boxtype
!= BOXTYPE_SAMYGO
)
6293 { dvbapi_write_ecminfo_file(client
, er
, demux
[i
].lastcw
[0], demux
[i
].lastcw
[1]); }
6298 cs_log_dbg(D_DVBAPI
, "Unhandled ECM response received for CAID %04X PROVID %06X ECMPID %04X CHID %04X VPID %04X",
6299 er
->caid
, er
->prid
, er
->pid
, er
->chid
, er
->vpid
);
6304 static int8_t isValidCW(uint8_t *cw
)
6307 for(i
= 0; i
< 16; i
+= 4)
6309 if(((cw
[i
] + cw
[i
+ 1] + cw
[i
+ 2]) & 0xff) != cw
[i
+ 3])
6317 void dvbapi_write_ecminfo_file(struct s_client
*client
, ECM_REQUEST
*er
, uint8_t* lastcw0
, uint8_t* lastcw1
)
6319 #define ECMINFO_TYPE_OSCAM 0
6320 #define ECMINFO_TYPE_OSCAM_MS 1
6321 #define ECMINFO_TYPE_WICARDD 2
6322 #define ECMINFO_TYPE_MGCAMD 3
6323 #define ECMINFO_TYPE_CCCAM 4
6324 #define ECMINFO_TYPE_CAMD3 5
6326 FILE *ecmtxt
= fopen(ECMINFO_FILE
, "w");
6327 if(ecmtxt
!= NULL
&& er
->rc
< E_NOTFOUND
)
6330 const char *reader_name
= NULL
, *from_name
= NULL
, *proto_name
= NULL
;
6332 int32_t from_port
= 0;
6333 char system_name
[64];
6334 const char* const_system_name
= get_cardsystem_desc_by_caid(er
->caid
);
6336 cs_strncpy(system_name
, const_system_name
, sizeof(system_name
));
6337 system_name
[0] = (char)toupper((int)system_name
[0]);
6339 if(cfg
.dvbapi_ecminfo_type
<= ECMINFO_TYPE_WICARDD
)
6341 if(cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_WICARDD
)
6343 fprintf(ecmtxt
, "system: %s\n", system_name
);
6346 fprintf(ecmtxt
, "caid: 0x%04X\npid: 0x%04X\n", er
->caid
, er
->pid
);
6348 if(cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_WICARDD
)
6350 fprintf(ecmtxt
, "prov: %06X\n", (uint
) er
->prid
);
6354 fprintf(ecmtxt
, "prov: 0x%06X\n", (uint
) er
->prid
);
6357 fprintf(ecmtxt
, "chid: 0x%04X\n", er
->chid
);
6359 else if(cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_MGCAMD
)
6361 fprintf(ecmtxt
, "===== %s ECM on CaID 0x%04X, pid 0x%04X =====\nprov: %06X\n", system_name
, er
->caid
, er
->pid
, (uint
) er
->prid
);
6363 else if(cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_CCCAM
)
6365 char provider_name
[128];
6366 get_providername(er
->prid
, er
->caid
, provider_name
, sizeof(provider_name
));
6367 if(provider_name
[0])
6369 fprintf(ecmtxt
, "system: %s\ncaid: 0x%04X\nprovider: %s\nprovid: 0x%06X\npid: 0x%04X\n",
6370 system_name
, er
->caid
, provider_name
, (uint
) er
->prid
, er
->pid
);
6374 fprintf(ecmtxt
, "system: %s\ncaid: 0x%04X\nprovid: 0x%06X\npid: 0x%04X\n", system_name
, er
->caid
, (uint
) er
->prid
, er
->pid
);
6377 else if(cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_CAMD3
)
6379 fprintf(ecmtxt
, "CAID 0x%04X, PID 0x%04X, PROVIDER 0x%06X\n", er
->caid
, er
->pid
, (uint
) er
->prid
);
6385 if(er
->selected_reader
)
6387 reader_name
= er
->selected_reader
->label
;
6388 if(is_network_reader(er
->selected_reader
))
6389 { from_name
= er
->selected_reader
->device
; }
6391 { from_name
= "local"; }
6392 from_port
= er
->selected_reader
->r_port
;
6393 proto_name
= reader_get_type_desc(er
->selected_reader
, 1);
6394 hops
= er
->selected_reader
->currenthops
;
6398 reader_name
= "none";
6399 from_name
= "local";
6400 proto_name
= "none";
6405 reader_name
= "Cache";
6406 from_name
= "cache1";
6407 proto_name
= "none";
6411 reader_name
= "Cache";
6412 from_name
= "cache2";
6413 proto_name
= "none";
6417 reader_name
= "Cache";
6418 from_name
= "cache3";
6419 proto_name
= "none";
6424 if(cfg
.dvbapi_ecminfo_type
<= ECMINFO_TYPE_OSCAM_MS
)
6429 if(er
->selected_reader
)
6431 fprintf(ecmtxt
, "reader: %s\nfrom: %s\nprotocol: %s\nhops: %d\n", reader_name
, from_name
, proto_name
, hops
);
6438 fprintf(ecmtxt
, "reader: %s\nfrom: %s\nprotocol: %s\n", reader_name
, from_name
, proto_name
);
6442 if(cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_OSCAM
)
6443 { fprintf(ecmtxt
, "ecm time: %.3f\n", (float) client
->cwlastresptime
/ 1000); }
6445 { fprintf(ecmtxt
, "ecm time: %d\n", client
->cwlastresptime
); }
6448 if(cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_CAMD3
)
6450 fprintf(ecmtxt
, "FROM: %s\n", reader_name
);
6451 fprintf(ecmtxt
, "CW0: %s\n", cs_hexdump(1, lastcw0
, 8, tmp
, sizeof(tmp
)));
6452 fprintf(ecmtxt
, "CW1: %s\n", cs_hexdump(1, lastcw1
, 8, tmp
, sizeof(tmp
)));
6456 fprintf(ecmtxt
, "cw0: %s\n", cs_hexdump(1, lastcw0
, 8, tmp
, sizeof(tmp
)));
6457 fprintf(ecmtxt
, "cw1: %s\n", cs_hexdump(1, lastcw1
, 8, tmp
, sizeof(tmp
)));
6460 if(cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_WICARDD
|| cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_MGCAMD
)
6466 fprintf(ecmtxt
, "Signature %s\n", (isValidCW(lastcw0
) || isValidCW(lastcw1
)) ? "OK" : "NOK");
6468 if(reader_name
!= NULL
)
6470 fprintf(ecmtxt
, "source: %s (%s at %s:%d)\n", reader_name
, proto_name
, from_name
, from_port
);
6473 walltime
= cs_time();
6474 localtime_r(&walltime
, <
);
6476 if(strftime(timebuf
, 32, "%a %b %d %H:%M:%S %Y", <
) != 0)
6478 fprintf(ecmtxt
, "%d msec -- %s\n", client
->cwlastresptime
, timebuf
);
6482 if(cfg
.dvbapi_ecminfo_type
== ECMINFO_TYPE_CCCAM
)
6484 if(reader_name
!= NULL
)
6486 fprintf(ecmtxt
, "using: %s\naddress: %s:%d\nhops: %d\n", proto_name
, from_name
, from_port
, hops
);
6489 fprintf(ecmtxt
, "ecm time: %d\n", client
->cwlastresptime
);
6495 int32_t ret
= fclose(ecmtxt
);
6496 if(ret
< 0) { cs_log("ERROR: Could not close ecmtxt fd (errno=%d %s)", errno
, strerror(errno
)); }
6502 void *dvbapi_start_handler(struct s_client
*cl
, uchar
*UNUSED(mbuf
), int32_t module_idx
, void * (*_main_func
)(void *))
6504 // cs_log("dvbapi loaded fd=%d", idx);
6505 if(cfg
.dvbapi_enabled
== 1)
6507 cl
= create_client(get_null_ip());
6508 cl
->module_idx
= module_idx
;
6510 int32_t ret
= start_thread("dvbapi handler", _main_func
, (void *) cl
, &cl
->thread
, 1, 0);
6520 void *dvbapi_handler(struct s_client
*cl
, uchar
*mbuf
, int32_t module_idx
)
6522 return dvbapi_start_handler(cl
, mbuf
, module_idx
, dvbapi_main_local
);
6525 int32_t dvbapi_set_section_filter(int32_t demux_index
, ECM_REQUEST
*er
, int32_t n
)
6527 if(!er
) { return -1; }
6534 if(selected_api
!= DVBAPI_3
&& selected_api
!= DVBAPI_1
&& selected_api
!= STAPI
) // only valid for dvbapi3, dvbapi1 and STAPI
6539 if(cfg
.dvbapi_boxtype
== BOXTYPE_IPBOX
|| cfg
.dvbapi_boxtype
== BOXTYPE_IPBOX_PMT
) // reported buggy using sectionfiltering after 1~4 hours -> for now disabled!
6546 n
= dvbapi_get_filternum(demux_index
, er
, TYPE_ECM
);
6549 if(n
< 0) { return -1; } // in case no valid filter found;
6551 int32_t fd
= demux
[demux_index
].demux_fd
[n
].fd
;
6552 if(fd
< 1) { return -1 ; } // in case no valid fd
6556 memset(filter
, 0, 16);
6557 memset(mask
, 0, 16);
6559 struct s_ecmpids
*curpid
= NULL
;
6560 int32_t pid
= demux
[demux_index
].demux_fd
[n
].pidindex
;
6563 curpid
= &demux
[demux_index
].ECMpids
[pid
];
6565 if(curpid
->table
!= er
->ecm
[0] && curpid
->table
!= 0) { return -1; } // if current ecmtype differs from latest requested ecmtype do not apply section filtering!
6566 uint8_t ecmfilter
= 0;
6568 if(er
->ecm
[0] == 0x80) { ecmfilter
= 0x81; } // current processed ecm is even, next will be filtered for odd
6569 else { ecmfilter
= 0x80; } // current processed ecm is odd, next will be filtered for even
6571 if(curpid
->table
!= 0) // cycle ecmtype from odd to even or even to odd
6573 filter
[0] = ecmfilter
; // only accept new ecms (if previous odd, filter for even and visaversa)
6575 cs_log_dbg(D_DVBAPI
, "Demuxer %d Filter %d set ecmtable to %s (CAID %04X PROVID %06X FD %d)", demux_index
, n
+ 1,
6576 (ecmfilter
== 0x80 ? "EVEN" : "ODD"), curpid
->CAID
, curpid
->PROVID
, fd
);
6578 else // not decoding right now so we are interessted in all ecmtypes!
6580 filter
[0] = 0x80; // set filter to wait for any ecms
6582 cs_log_dbg(D_DVBAPI
, "Demuxer %d Filter %d set ecmtable to ODD+EVEN (CAID %04X PROVID %06X FD %d)", demux_index
, n
+ 1,
6583 curpid
->CAID
, curpid
->PROVID
, fd
);
6585 uint32_t offset
= 0, extramask
= 0xFF;
6587 struct s_dvbapi_priority
*forceentry
= dvbapi_check_prio_match(demux_index
, pid
, 'p');
6588 //cs_log("**** curpid->CHID %04X, checked = %d, er->chid = %04X *****", curpid->CHID, curpid->checked, er->chid);
6589 // checked 4 to make sure we dont set chid filter and no such ecm in dvbstream except for forced pids!
6590 if(curpid
->CHID
< 0x10000 && (curpid
->checked
== 4 || (forceentry
&& forceentry
->force
)))
6593 switch(er
->caid
>> 8)
6607 break; // videoguard
6608 case 0x4A: // DRE-Crypt, Bulcrypt,Tongang and others?
6609 if(!caid_is_bulcrypt(er
->caid
))
6615 int32_t irdetomatch
= 1; // check if wanted irdeto index is the one the delivers current chid!
6616 if(caid_is_irdeto(curpid
->CAID
))
6618 if(curpid
->irdeto_curindex
== er
->ecm
[4]) { irdetomatch
= 1; } // ok apply chid filtering
6619 else { irdetomatch
= 0; } // skip chid filtering but apply irdeto index filtering
6622 if(offset
&& irdetomatch
) // we have a cas with chid or unique part in checked ecm
6624 i2b_buf(2, curpid
->CHID
, filter
+ (offset
- 2));
6625 mask
[(offset
- 2)] = 0xFF&extramask
; // additional mask seca2 chid can be FC10 or FD10 varies each month so only apply F?10
6626 mask
[(offset
- 1)] = 0xFF;
6627 cs_log_dbg(D_DVBAPI
, "Demuxer %d Filter %d set chid to %04X on fd %d", demux_index
, n
+ 1, curpid
->CHID
, fd
);
6631 if(caid_is_irdeto(curpid
->CAID
) && (curpid
->irdeto_curindex
< 0xFE)) // on irdeto we can always apply irdeto index filtering!
6633 filter
[2] = curpid
->irdeto_curindex
;
6635 cs_log_dbg(D_DVBAPI
, "Demuxer %d Filter %d set irdetoindex to %d on fd %d", demux_index
, n
+ 1, curpid
->irdeto_curindex
, fd
);
6637 else // all other cas systems also cas systems without chid or unique ecm part
6639 cs_log_dbg(D_DVBAPI
, "Demuxer %d Filter %d set chid to ANY CHID on fd %d", demux_index
, n
+ 1, fd
);
6643 int32_t ret
= dvbapi_activate_section_filter(demux_index
, n
, fd
, curpid
->ECM_PID
, filter
, mask
, er
->msgid
);
6644 if(ret
< 0) // something went wrong setting filter!
6646 cs_log("Demuxer %d Filter %d (fd %d) error setting section filtering -> stop filter!", demux_index
, n
+ 1, fd
);
6647 ret
= dvbapi_stop_filternum(demux_index
, n
, er
->msgid
);
6650 cs_log("Demuxer %d Filter %d (fd %d) stopping filter failed -> kill all filters of this demuxer!", demux_index
, n
+ 1, fd
);
6651 dvbapi_stop_filter(demux_index
, TYPE_EMM
, er
->msgid
);
6652 dvbapi_stop_filter(demux_index
, TYPE_ECM
, er
->msgid
);
6659 int32_t dvbapi_activate_section_filter(int32_t demux_index
, int32_t num
, int32_t fd
, int32_t pid
, uchar
*filter
, uchar
*mask
, uint32_t msgid
)
6664 switch(selected_api
)
6668 struct dmx_sct_filter_params sFP2
;
6669 memset(&sFP2
, 0, sizeof(sFP2
));
6672 sFP2
.flags
= DMX_IMMEDIATE_START
;
6673 if(cfg
.dvbapi_boxtype
== BOXTYPE_NEUMO
)
6675 //DeepThought: on dgs/cubestation and neumo images, perhaps others
6676 //the following code is needed to descramble
6677 sFP2
.filter
.filter
[0] = filter
[0];
6678 sFP2
.filter
.mask
[0] = mask
[0];
6679 sFP2
.filter
.filter
[1] = 0;
6680 sFP2
.filter
.mask
[1] = 0;
6681 sFP2
.filter
.filter
[2] = 0;
6682 sFP2
.filter
.mask
[2] = 0;
6683 memcpy(sFP2
.filter
.filter
+ 3, filter
+ 1, 16 - 3);
6684 memcpy(sFP2
.filter
.mask
+ 3, mask
+ 1, 16 - 3);
6685 //DeepThought: in the drivers of the dgs/cubestation and neumo images,
6686 //dvbapi 1 and 3 are somehow mixed. In the kernel drivers, the DMX_SET_FILTER
6687 //ioctl expects to receive a dmx_sct_filter_params structure (DVBAPI 3) but
6688 //due to a bug its sets the "positive mask" wrongly (they should be all 0).
6689 //On the other hand, the DMX_SET_FILTER1 ioctl also uses the dmx_sct_filter_params
6690 //structure, which is incorrect (it should be dmxSctFilterParams).
6691 //The only way to get it right is to call DMX_SET_FILTER1 with the argument
6692 //expected by DMX_SET_FILTER. Otherwise, the timeout parameter is not passed correctly.
6693 ret
= dvbapi_ioctl(fd
, DMX_SET_FILTER1
, &sFP2
);
6697 memcpy(sFP2
.filter
.filter
, filter
, 16);
6698 memcpy(sFP2
.filter
.mask
, mask
, 16);
6699 if (cfg
.dvbapi_listenport
|| cfg
.dvbapi_boxtype
== BOXTYPE_PC_NODMX
)
6700 ret
= dvbapi_net_send(DVBAPI_DMX_SET_FILTER
, demux
[demux_index
].socket_fd
, msgid
, demux_index
, num
, (unsigned char *) &sFP2
, NULL
, NULL
, demux
[demux_index
].client_proto_version
);
6702 ret
= dvbapi_ioctl(fd
, DMX_SET_FILTER
, &sFP2
);
6709 struct dmxSctFilterParams sFP1
;
6710 memset(&sFP1
, 0, sizeof(sFP1
));
6713 sFP1
.flags
= DMX_IMMEDIATE_START
;
6714 memcpy(sFP1
.filter
.filter
, filter
, 16);
6715 memcpy(sFP1
.filter
.mask
, mask
, 16);
6716 ret
= dvbapi_ioctl(fd
, DMX_SET_FILTER1
, &sFP1
);
6719 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
6722 ret
= stapi_activate_section_filter(fd
, filter
, mask
);
6726 // Isn't implemented in COOLAPI-1 (legacy)
6727 #if defined WITH_COOLAPI2
6730 int32_t n
= coolapi_get_filter_num(fd
);
6733 coolapi_set_filter(fd
, n
, pid
, filter
, mask
, TYPE_ECM
);
6741 if(ret
!=-1) // only change filter/mask for comparing if box returned no errors!
6743 memcpy(demux
[demux_index
].demux_fd
[num
].filter
, filter
, 16); // copy filter to check later on if receiver delivered accordingly
6744 memcpy(demux
[demux_index
].demux_fd
[num
].mask
, mask
, 16); // copy mask to check later on if receiver delivered accordingly
6750 int32_t dvbapi_check_ecm_delayed_delivery(int32_t demux_index
, ECM_REQUEST
*er
)
6753 int32_t filternum
= dvbapi_get_filternum(demux_index
, er
, TYPE_ECM
);
6754 char nullcw
[CS_ECMSTORESIZE
];
6755 memset(nullcw
, 0, CS_ECMSTORESIZE
);
6757 if(filternum
< 0) { return 2; } // if no matching filter act like ecm response is delayed
6758 if(memcmp(demux
[demux_index
].demux_fd
[filternum
].lastecmd5
, nullcw
, CS_ECMSTORESIZE
))
6760 demux
[demux_index
].demux_fd
[filternum
].lastresult
= er
->rc
; // save last result
6762 cs_hexdump(0, er
->ecmd5
, 16, ecmd5
, sizeof(ecmd5
));
6763 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
);
6764 unsigned char md5tmp
[MD5_DIGEST_LENGTH
];
6765 MD5(er
->ecm
, er
->ecmlen
, md5tmp
);
6766 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!
6769 // 0x2600 used by biss and constant cw could be zero but every other caid received a null cw -> not usable!
6770 if(memcmp(er
->cw
, nullcw
, 8) == 0 && memcmp(er
->cw
+8, nullcw
, 8) == 0 && er
->caid
!=0x2600) {return 5;}
6771 struct s_ecmpids
*curpid
= NULL
;
6773 int32_t pid
= demux
[demux_index
].demux_fd
[filternum
].pidindex
;
6777 curpid
= &demux
[demux_index
].ECMpids
[pid
];
6778 if(curpid
->table
== 0) { return 3; } // on change table act like ecm response is found
6781 if(er
->rc
== E_CACHEEX
) { return 4; } // on cache-ex response act like ecm response is found
6787 int32_t dvbapi_get_filternum(int32_t demux_index
, ECM_REQUEST
*er
, int32_t type
)
6789 if(!er
) { return -1; }
6794 for(n
= 0; n
< maxfilter
; n
++) // determine fd
6796 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)
6798 if(type
== TYPE_ECM
&& er
->srvid
!= demux
[demux_index
].program_number
) continue;
6799 if((demux
[demux_index
].demux_fd
[n
].pid
== er
->pid
) &&
6800 ((demux
[demux_index
].demux_fd
[n
].provid
== er
->prid
) || demux
[demux_index
].demux_fd
[n
].provid
== 0 || er
->prid
== 0) &&
6801 ((demux
[demux_index
].demux_fd
[n
].caid
== er
->caid
) || (demux
[demux_index
].demux_fd
[n
].caid
== er
->ocaid
))) // current ecm pid?
6803 fd
= demux
[demux_index
].demux_fd
[n
].fd
; // found!
6804 if(demux
[demux_index
].demux_fd
[n
].caid
== er
->ocaid
)
6806 memset(demux
[demux_index
].demux_fd
[n
].lastecmd5
, 0, CS_ECMSTORESIZE
); // clear ecmd5 hash since betatunneled ecms hash different!
6812 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
6814 return (fd
> 0 ? n
: fd
); // return -1(fd) on not found, on found return filternumber(n)
6817 ca_index_t
dvbapi_ca_setpid(int32_t demux_index
, int32_t pid
, int32_t stream_id
, bool use_des
, uint32_t msgid
)
6822 if(pid
== -1 || pid
> demux
[demux_index
].ECMpidcount
) return INDEX_INVALID
;
6824 if(demux
[demux_index
].ECMpids
[pid
].useMultipleIndices
)
6827 idx
= demux
[demux_index
].ECMpids
[pid
].index
[n
];
6829 if(idx
== INDEX_INVALID
) // if no indexer for this pid get one!
6831 idx
= dvbapi_get_descindex(demux_index
, pid
, n
);
6832 if(idx
== INDEX_INVALID
)
6834 cs_log_dbg(D_DVBAPI
, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X has no free index", demux_index
, pid
,
6835 demux
[demux_index
].ECMpids
[pid
].CAID
, demux
[demux_index
].ECMpids
[pid
].ECM_PID
);
6836 return INDEX_INVALID
;
6839 cs_log_dbg(D_DVBAPI
, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X is using index %d for stream %d", demux_index
, pid
,
6840 demux
[demux_index
].ECMpids
[pid
].CAID
, demux
[demux_index
].ECMpids
[pid
].ECM_PID
, idx
, n
);
6843 if(!demux
[demux_index
].ECMpids
[pid
].streams
|| ((demux
[demux_index
].ECMpids
[pid
].streams
& (1 << n
)) == (uint
) (1 << n
)))
6845 dvbapi_set_pid(demux_index
, n
, idx
, true, use_des
, msgid
); // enable streampid
6849 dvbapi_set_pid(demux_index
, n
, idx
, false, false, msgid
); // disable streampid
6854 idx
= demux
[demux_index
].ECMpids
[pid
].index
[0];
6856 if(idx
== INDEX_INVALID
) // if no indexer for this pid get one!
6858 idx
= dvbapi_get_descindex(demux_index
, pid
, 0);
6859 if(idx
== INDEX_INVALID
)
6861 cs_log_dbg(D_DVBAPI
, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X has no free index", demux_index
, pid
,
6862 demux
[demux_index
].ECMpids
[pid
].CAID
, demux
[demux_index
].ECMpids
[pid
].ECM_PID
);
6863 return INDEX_INVALID
;
6866 cs_log_dbg(D_DVBAPI
, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X is using index %d", demux_index
, pid
,
6867 demux
[demux_index
].ECMpids
[pid
].CAID
, demux
[demux_index
].ECMpids
[pid
].ECM_PID
, idx
);
6870 for(n
= 0; n
< demux
[demux_index
].STREAMpidcount
; n
++)
6872 if(!demux
[demux_index
].ECMpids
[pid
].streams
|| ((demux
[demux_index
].ECMpids
[pid
].streams
& (1 << n
)) == (uint
) (1 << n
)))
6874 dvbapi_set_pid(demux_index
, n
, idx
, true, use_des
, 0); // enable streampid
6878 dvbapi_set_pid(demux_index
, n
, idx
, false, false, 0); // disable streampid
6883 return idx
; // return caindexer
6886 int8_t update_streampid_list(uint8_t cadevice
, uint16_t pid
, ca_index_t idx
, bool use_des
)
6888 struct s_streampid
*listitem
, *newlistitem
;
6891 if(!ll_activestreampids
)
6892 { ll_activestreampids
= ll_create("ll_activestreampids"); }
6895 { return INVALID_STREAMPID_INDEX
; }
6897 if(ll_count(ll_activestreampids
) > 0)
6899 itr
= ll_iter_create(ll_activestreampids
);
6900 while((listitem
= ll_iter_next(&itr
)))
6902 if (cadevice
== listitem
->cadevice
&& pid
== listitem
->streampid
){
6903 if((listitem
->activeindexers
& (1 << idx
)) == (uint64_t) (1 << idx
)){
6905 if(cfg
.dvbapi_extended_cw_api
== 2 && use_des
!= listitem
->use_des
)
6907 listitem
->use_des
= use_des
;
6908 return FIRST_STREAMPID_INDEX
;
6911 return FOUND_STREAMPID_INDEX
; // match found
6913 listitem
->activeindexers
|=(1 << idx
); // ca + pid found but not this index -> add this index
6914 cs_log_dbg(D_DVBAPI
, "Added existing streampid %04X with new index %d to ca%d", pid
, idx
, cadevice
);
6916 if(cfg
.dvbapi_extended_cw_api
== 2 && use_des
!= listitem
->use_des
)
6918 listitem
->use_des
= use_des
;
6919 return FIRST_STREAMPID_INDEX
;
6922 return ADDED_STREAMPID_INDEX
;
6927 if(!cs_malloc(&newlistitem
, sizeof(struct s_streampid
)))
6928 { return FIRST_STREAMPID_INDEX
; }
6929 newlistitem
->cadevice
= cadevice
;
6930 newlistitem
->streampid
= pid
;
6931 newlistitem
->activeindexers
= (1 << idx
);
6932 newlistitem
->caindex
= idx
; // set this index as used to decode on ca device
6933 newlistitem
->use_des
= use_des
;
6934 ll_append(ll_activestreampids
, newlistitem
);
6935 cs_log_dbg(D_DVBAPI
, "Added new streampid %04X with index %d to ca%d", pid
, idx
, cadevice
);
6936 return FIRST_STREAMPID_INDEX
;
6939 int8_t remove_streampid_from_list(uint8_t cadevice
, uint16_t pid
, ca_index_t idx
)
6941 struct s_streampid
*listitem
;
6945 if(!ll_activestreampids
)
6946 { return NO_STREAMPID_LISTED
; }
6949 { return INVALID_STREAMPID_INDEX
; }
6951 if(ll_count(ll_activestreampids
) > 0)
6953 itr
= ll_iter_create(ll_activestreampids
);
6954 while((listitem
= ll_iter_next(&itr
)))
6956 if (cadevice
== listitem
->cadevice
&& pid
== listitem
->streampid
)
6958 if(idx
== INDEX_DISABLE_ALL
) {
6959 listitem
->activeindexers
= 0;
6962 else if((listitem
->activeindexers
& (1 << idx
)) == (uint64_t) (1 << idx
))
6964 listitem
->activeindexers
&= ~(1 << idx
); // flag it as disabled for this index
6970 cs_log_dbg(D_DVBAPI
, "Remove streampid %04X using indexer %d from ca%d", pid
, idx
, cadevice
);
6972 if (listitem
->activeindexers
== 0 && removed
== 1) // all indexers disabled? -> remove pid from list!
6974 ll_iter_remove_data(&itr
);
6975 cs_log_dbg(D_DVBAPI
, "Removed last indexer of streampid %04X from ca%d", pid
, cadevice
);
6976 return REMOVED_STREAMPID_LASTINDEX
;
6978 else if(removed
== 1)
6980 if (idx
!= INDEX_DISABLE_ALL
&& idx
!= listitem
->caindex
)
6982 return REMOVED_STREAMPID_INDEX
;
6986 listitem
->caindex
= INDEX_INVALID
;
6987 cs_log_dbg(D_DVBAPI
, "Streampid %04X index %d was used for decoding on ca%d", pid
, idx
, cadevice
);
6988 return REMOVED_DECODING_STREAMPID_INDEX
;
6991 return INVALID_STREAMPID_INDEX
;
6995 return NO_STREAMPID_LISTED
;
6998 void disable_unused_streampids(int16_t demux_id
)
7000 if(selected_api
== STAPI
) return; // stapi handles pids itself!
7002 if(!ll_activestreampids
) return;
7003 if(ll_count(ll_activestreampids
) == 0) return; // no items in list?
7005 int32_t ecmpid
= demux
[demux_id
].pidindex
;
7006 if (ecmpid
== -1) return; // no active ecmpid!
7010 if(demux
[demux_id
].ECMpids
[ecmpid
].useMultipleIndices
== 0)
7012 ca_index_t idx
= demux
[demux_id
].ECMpids
[ecmpid
].index
[0];
7014 struct s_streampid
*listitem
;
7015 // search for old enabled streampids on all ca devices that have to be disabled
7016 for(i
= 0; i
< MAX_DEMUX
&& idx
!= INDEX_INVALID
; i
++)
7018 if(!((demux
[demux_id
].ca_mask
& (1 << i
)) == (uint32_t) (1 << i
))) continue; // continue if ca is unused by this demuxer
7021 itr
= ll_iter_create(ll_activestreampids
);
7022 while((listitem
= ll_iter_next(&itr
)))
7024 if (i
!= listitem
->cadevice
) continue; // ca doesnt match
7025 if (!((listitem
->activeindexers
& (1 << (idx
))) == (uint64_t) (1 << (idx
)))) continue; // index doesnt match
7026 for(n
= 0; n
< demux
[demux_id
].STREAMpidcount
; n
++){
7027 if(demux
[demux_id
].ECMpidcount
== 0) // FTA? -> disable stream!
7029 n
= demux
[demux_id
].STREAMpidcount
;
7032 if (listitem
->streampid
== demux
[demux_id
].STREAMpids
[n
]){ // check if pid matches with current streampid on demuxer
7036 if (n
== demux
[demux_id
].STREAMpidcount
){
7037 demux
[demux_id
].STREAMpids
[n
] = listitem
->streampid
; // put it temp here!
7038 dvbapi_set_pid(demux_id
, n
, idx
, false, false, 0); // no match found so disable this now unused streampid
7039 demux
[demux_id
].STREAMpids
[n
] = 0; // remove temp!
7043 for(n
= 0; n
< demux
[demux_id
].STREAMpidcount
&& demux
[demux_id
].ECMpidcount
!= 0; n
++) // ECMpidcount != 0 -> skip enabling on fta
7045 ll_iter_reset(&itr
);
7046 if(!demux
[demux_id
].ECMpids
[ecmpid
].streams
|| ((demux
[demux_id
].ECMpids
[ecmpid
].streams
& (1 << n
)) == (uint
) (1 << n
)))
7048 while((listitem
= ll_iter_next(&itr
)))
7050 if (i
!= listitem
->cadevice
) continue; // ca doesnt match
7051 if (!((listitem
->activeindexers
& (1 << (idx
))) == (uint64_t) (1 << (idx
)))) continue; // index doesnt match
7052 if (listitem
->streampid
== demux
[demux_id
].STREAMpids
[n
]) // check if pid matches with current streampid on demuxer
7057 if(!listitem
) // if streampid not listed -> enable it!
7059 dvbapi_set_pid(demux_id
, n
, idx
, true, false, 0); // enable streampid
7067 ca_index_t idx
= INDEX_INVALID
;
7070 struct s_streampid
*listitem
;
7071 // search for old enabled streampids on all ca devices that have to be disabled
7072 for(i
= 0; i
< MAX_DEMUX
&& idx
!= INDEX_INVALID
; i
++)
7074 if(!((demux
[demux_id
].ca_mask
& (1 << i
)) == (uint32_t) (1 << i
))) continue; // continue if ca is unused by this demuxer
7077 itr
= ll_iter_create(ll_activestreampids
);
7078 while((listitem
= ll_iter_next(&itr
)))
7080 if (i
!= listitem
->cadevice
) continue; // ca doesnt match
7082 for(skip
= 1, j
= 0; j
< MAX_STREAM_INDICES
; j
++)
7084 idx
= demux
[demux_id
].ECMpids
[ecmpid
].index
[j
];
7085 if(idx
== INDEX_INVALID
) continue;
7087 if ((listitem
->activeindexers
& (1 << (idx
))) == (uint64_t) (1 << (idx
)))
7089 skip
= 0; // index match
7096 for(n
= 0; n
< demux
[demux_id
].STREAMpidcount
; n
++){
7097 if(demux
[demux_id
].ECMpidcount
== 0) // FTA? -> disable stream!
7099 n
= demux
[demux_id
].STREAMpidcount
;
7102 if (listitem
->streampid
== demux
[demux_id
].STREAMpids
[n
]){ // check if pid matches with current streampid on demuxer
7106 if (n
== demux
[demux_id
].STREAMpidcount
){
7107 demux
[demux_id
].STREAMpids
[n
] = listitem
->streampid
; // put it temp here!
7108 dvbapi_set_pid(demux_id
, n
, idx
, false, false, 0); // no match found so disable this now unused streampid
7109 demux
[demux_id
].STREAMpids
[n
] = 0; // remove temp!
7113 for(n
= 0; n
< demux
[demux_id
].STREAMpidcount
&& demux
[demux_id
].ECMpidcount
!= 0; n
++) // ECMpidcount != 0 -> skip enabling on fta
7115 ll_iter_reset(&itr
);
7116 if(!demux
[demux_id
].ECMpids
[ecmpid
].streams
|| ((demux
[demux_id
].ECMpids
[ecmpid
].streams
& (1 << n
)) == (uint
) (1 << n
)))
7118 while((listitem
= ll_iter_next(&itr
)))
7120 if (i
!= listitem
->cadevice
) continue; // ca doesnt match
7122 for(skip
= 1, j
= 0; j
< MAX_STREAM_INDICES
; j
++)
7124 idx
= demux
[demux_id
].ECMpids
[ecmpid
].index
[j
];
7125 if(idx
== INDEX_INVALID
) continue;
7127 if ((listitem
->activeindexers
& (1 << (idx
))) == (uint64_t) (1 << (idx
)))
7129 skip
= 0; // index match
7136 if (listitem
->streampid
== demux
[demux_id
].STREAMpids
[n
]) // check if pid matches with current streampid on demuxer
7141 if(!listitem
) // if streampid not listed -> enable it!
7143 dvbapi_set_pid(demux_id
, n
, idx
, true, false, 0); // enable streampid
7152 ca_index_t
is_ca_used(uint8_t cadevice
, int32_t pid
)
7154 struct s_streampid
*listitem
;
7157 if(!ll_activestreampids
)
7158 { return INDEX_INVALID
; }
7160 if(ll_count(ll_activestreampids
) > 0)
7162 itr
= ll_iter_create(ll_activestreampids
);
7163 while((listitem
= ll_iter_next(&itr
)))
7165 if(listitem
->cadevice
!= cadevice
)
7168 if(pid
&& listitem
->streampid
!= pid
)
7172 while(listitem
->caindex
== INDEX_INVALID
&& i
<= INDEX_MAX
)
7174 if((listitem
->activeindexers
&(1 << i
)) == (uint64_t)(1 << i
))
7176 listitem
->caindex
= i
; // set fresh one
7177 cs_log_dbg(D_DVBAPI
, "Streampid %04X is now using index %d for decoding on ca%d", pid
, i
, cadevice
);
7183 if(listitem
->caindex
== INDEX_INVALID
)
7185 ll_iter_remove_data(&itr
);
7186 return INDEX_INVALID
;
7189 return listitem
->caindex
;
7192 return INDEX_INVALID
; // no indexer found for this pid!
7195 uint16_t dvbapi_get_client_proto_version(void)
7197 return last_client_proto_version
;
7200 const char *dvbapi_get_client_name(void)
7202 return last_client_name
? last_client_name
: "";
7205 void check_add_emmpid(int32_t demux_index
, uchar
*filter
, int32_t l
, int32_t emmtype
)
7209 uint32_t typtext_idx
= 0;
7211 const char *typtext
[] = { "UNIQUE", "SHARED", "GLOBAL", "UNKNOWN" };
7213 while(((emmtype
>> typtext_idx
) & 0x01) == 0 && typtext_idx
< sizeof(typtext
) / sizeof(const char *))
7218 //filter already in list?
7219 if(is_emmfilter_in_list(filter
, demux
[demux_index
].EMMpids
[l
].PID
, demux
[demux_index
].EMMpids
[l
].PROVID
, demux
[demux_index
].EMMpids
[l
].CAID
))
7221 cs_log_dbg(D_DVBAPI
, "Demuxer %d duplicate emm filter type %s, emmpid: 0x%04X, emmcaid: %04X, emmprovid: %06X -> SKIPPED!", demux_index
,
7222 typtext
[typtext_idx
], demux
[demux_index
].EMMpids
[l
].PID
, demux
[demux_index
].EMMpids
[l
].CAID
, demux
[demux_index
].EMMpids
[l
].PROVID
);
7226 if(demux
[demux_index
].emm_filter
< demux
[demux_index
].max_emm_filter
) // can this filter be started?
7228 // try to activate this emmfilter
7229 ret
= dvbapi_set_filter(demux_index
, selected_api
, demux
[demux_index
].EMMpids
[l
].PID
, demux
[demux_index
].EMMpids
[l
].CAID
,
7230 demux
[demux_index
].EMMpids
[l
].PROVID
, filter
, filter
+ 16, 0, demux
[demux_index
].pidindex
, TYPE_EMM
, 1);
7233 if(ret
!= -1) // -1 if maxfilter reached or filter start error!
7235 if(demux
[demux_index
].emm_filter
== -1) // -1: first run of emm filtering on this demuxer
7237 demux
[demux_index
].emm_filter
= 0;
7239 demux
[demux_index
].emm_filter
++; // increase total active filters
7240 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
);
7243 else // not set successful, so add it to the list for try again later on!
7245 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);
7246 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
);
7251 void rotate_emmfilter(int32_t demux_id
)
7253 // emm filter iteration
7254 if(!ll_emm_active_filter
)
7255 { ll_emm_active_filter
= ll_create("ll_emm_active_filter"); }
7257 if(!ll_emm_inactive_filter
)
7258 { ll_emm_inactive_filter
= ll_create("ll_emm_inactive_filter"); }
7260 if(!ll_emm_pending_filter
)
7261 { ll_emm_pending_filter
= ll_create("ll_emm_pending_filter"); }
7263 uint32_t filter_count
= ll_count(ll_emm_active_filter
) + ll_count(ll_emm_inactive_filter
);
7265 if(demux
[demux_id
].max_emm_filter
> 0
7266 && ll_count(ll_emm_inactive_filter
) > 0
7267 && filter_count
> demux
[demux_id
].max_emm_filter
)
7270 int32_t filter_queue
= ll_count(ll_emm_inactive_filter
);
7271 int32_t stopped
= 0, started
= 0;
7275 struct s_emm_filter
*filter_item
;
7277 itr
= ll_iter_create(ll_emm_active_filter
);
7279 while((filter_item
= ll_iter_next(&itr
)) != NULL
)
7281 if(!ll_count(ll_emm_inactive_filter
) || started
== filter_queue
)
7283 int64_t gone
= comp_timeb(&now
, &filter_item
->time_started
);
7286 struct s_dvbapi_priority
*forceentry
= dvbapi_check_prio_match_emmpid(filter_item
->demux_id
, filter_item
->caid
,
7287 filter_item
->provid
, 'p');
7289 if(!forceentry
|| (forceentry
&& !forceentry
->force
))
7291 // stop active filter and add to pending list
7292 dvbapi_stop_filternum(filter_item
->demux_id
, filter_item
->num
- 1, 0);
7293 ll_iter_remove_data(&itr
);
7294 add_emmfilter_to_list(filter_item
->demux_id
, filter_item
->filter
, filter_item
->caid
,
7295 filter_item
->provid
, filter_item
->pid
, -1, false);
7301 if(stopped
> started
) // we have room for new filters, try to start an inactive emmfilter!
7303 struct s_emm_filter
*filter_item2
;
7304 LL_ITER itr2
= ll_iter_create(ll_emm_inactive_filter
);
7306 while((filter_item2
= ll_iter_next(&itr2
)))
7308 ret
= dvbapi_set_filter(filter_item2
->demux_id
, selected_api
, filter_item2
->pid
, filter_item2
->caid
,
7309 filter_item2
->provid
, filter_item2
->filter
, filter_item2
->filter
+ 16, 0,
7310 demux
[filter_item2
->demux_id
].pidindex
, TYPE_EMM
, 1);
7313 ll_iter_remove_data(&itr2
);
7321 itr
= ll_iter_create(ll_emm_pending_filter
);
7323 while((filter_item
= ll_iter_next(&itr
)) != NULL
) // move pending filters to inactive
7325 add_emmfilter_to_list(filter_item
->demux_id
, filter_item
->filter
, filter_item
->caid
, filter_item
->provid
, filter_item
->pid
, 0, false);
7326 ll_iter_remove_data(&itr
);
7331 int32_t filtermatch(uchar
*buffer
, int32_t filter_num
, int32_t demux_id
, int32_t len
)
7333 int32_t i
, k
, match
;
7336 for(i
= 0, k
= 0; i
< 16 && match
; i
++, k
++)
7338 mask
= demux
[demux_id
].demux_fd
[filter_num
].mask
[i
];
7339 if(k
== 1) //skip len bytes
7347 flt
= (demux
[demux_id
].demux_fd
[filter_num
].filter
[i
]&mask
);
7348 //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,
7349 // demux[demux_id].demux_fd[filter_num].filter[i], i, mask, flt&mask, k, buffer[k], k, buffer[k] & mask);
7352 match
= (flt
== (buffer
[k
] & mask
));
7359 return (match
&& i
== 16); // 0 = delivered data does not match with filter, 1 = delivered data matches with filter
7363 * protocol structure
7366 void module_dvbapi(struct s_module
*ph
)
7368 ph
->desc
= "dvbapi";
7369 ph
->type
= MOD_CONN_SERIAL
;
7370 ph
->listenertype
= LIS_DVBAPI
;
7371 #if defined(WITH_AZBOX)
7372 ph
->s_handler
= azbox_handler
;
7373 ph
->send_dcw
= azbox_send_dcw
;
7374 #elif defined(WITH_MCA)
7375 ph
->s_handler
= mca_handler
;
7376 ph
->send_dcw
= mca_send_dcw
;
7377 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
7379 ph
->s_handler
= dvbapi_handler
;
7380 ph
->send_dcw
= dvbapi_send_dcw
;
7383 #endif // HAVE_DVBAPI