DVBAPI: parse pmtpid also for PC clients
[oscam.git] / module-dvbapi.c
blobdd79e4cdc3a1132a8422006735b59b6f83f990cb
1 #define MODULE_LOG_PREFIX "dvbapi"
3 #include "globals.h"
5 #ifdef HAVE_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__)
32 #define F_NOTIFY 0
33 #define F_SETSIG 0
34 #define DN_MODIFY 0
35 #define DN_CREATE 0
36 #define DN_DELETE 0
37 #define DN_MULTISHOT 0
38 #endif
40 const char *streamtxt_00_to_1B[] = {
41 "Reserved", // 00
42 "Videostream (MPEG-1)", // 01
43 "Videostream (MPEG-2)", // 02
44 "Audiostream (MPEG-1)", // 03
45 "Audiostream (MPEG-2)", // 04
46 "Datastream (MPEG-2 tabled data)", // 05
47 "Data-/Audiostream (Subtitles/VBI and AC-3)", // 06
48 "Datastream (MHEG)", // 07
49 "Datastream (DSM CC)", // 08
50 "Conditional Access ", // 09
51 "Datastream (DSM CC)", // 0A
52 "Datastream (DSM CC)", // 0B
53 "Datastream (DSM CC)", // 0C
54 "Datastream (DSM CC)", // 0D
55 "Datastream (Auxiliary)", // 0E
56 "Audiostream (MPEG-2)", // 0F
57 "Videostream (MPEG-4 H.263)", // 10
58 "Audiostream (MPEG-4)", // 11
59 "Datastream (MPEG-4 FlexMux)", // 12
60 "Datastream (MPEG-4 FlexMux)", // 13
61 "Datastream (DSM CC)", // 14
62 "Datastream (Metadata)", // 15
63 "Datastream (Metadata)", // 16
64 "Datastream (DSM CC)", // 17
65 "Datastream (DSM CC)", // 18
66 "Datastream (Metadata)", // 19
67 "Datastream (IPMP)", // 1A
68 "Videostream (MPEG-4)", // 1B
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)
84 if(id <= 0x1B)
86 return streamtxt_00_to_1B[id];
88 else if(id == 0x24)
90 return "Videostream (H.265 Ultra HD video)";
92 else if(id == 0x42)
94 return "Videostream (Chinese Video Standard)";
96 else if(id >= 0x80 && id <= 0x87)
98 return streamtxt_80_to_87[id - 0x80];
100 else if(id == 0x90)
102 return "Datastream (Blu-ray subtitling)";
104 else if(id == 0x95)
106 return "Datastream (DSM CC)";
108 else if(id == 0xC0)
110 return "Datastream (DigiCipher II text)";
112 else if(id == 0xC2)
114 return "Datastream (DSM CC)";
116 else if(id == 0xD1)
118 return "Videostream (BBC Dirac Ultra HD video)";
120 else if(id == 0xEA)
122 return "Videostream (WMV9 lower bit-rate)";
124 else
126 return "Reserved";
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);
136 fd_set rd;
137 struct timeval t;
138 char buff[100];
139 t.tv_sec=0;
140 t.tv_usec=0;
141 FD_ZERO(&rd);
142 FD_SET(fd,&rd);
143 while(select(fd+1,&rd,NULL,NULL,&t) > 0)
145 if (read(fd,buff,100)){;}
150 static int dvbapi_ioctl(int fd, uint32_t request, ...)
152 int ret = 0;
153 va_list args;
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);
160 else
162 switch(request)
164 case DMX_SET_FILTER:
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);
176 // prepare packet
177 unsigned char packet[sizeof(request) + sizeof(struct dmx_sct_filter_params)];
178 memcpy(&packet, &request, sizeof(request));
179 memcpy(&packet[sizeof(request)], sFP, sizeof(struct dmx_sct_filter_params));
180 ret = send(fd, packet, sizeof(packet), 0);
181 break;
183 case DMX_SET_FILTER1:
185 cs_log("error: samygo does not support DMX_SET_FILTER1");
186 ret = -1;
187 break;
189 case DMX_STOP:
191 ret = send(fd, &request, sizeof(request), 0);
192 ret = 1;
193 break;
195 case CA_SET_PID:
197 ca_pid_t *ca_pid2 = va_arg(args, ca_pid_t *);
199 // preparing packet
200 unsigned char packet[sizeof(request) + sizeof(ca_pid_t)];
201 memcpy(&packet[0], &request, sizeof(request));
202 memcpy(&packet[sizeof(request)], ca_pid2, sizeof(ca_pid_t));
204 // sending data to UDP
205 ret = send(fd, &packet[0], sizeof(packet), 0);
206 break;
208 case CA_SET_DESCR:
210 ca_descr_t *ca_descr = va_arg(args, ca_descr_t *);
212 // preparing packet
213 unsigned char packet[sizeof(request) + sizeof(ca_descr_t)];
214 memcpy(&packet[0], &request, sizeof(request));
215 memcpy(&packet[sizeof(request)], ca_descr, sizeof(ca_descr_t));
217 // sending data to UDP
218 ret = send(fd, &packet[0], sizeof(packet), 0);
219 break;
221 case CA_SET_DESCR_MODE:
223 cs_log("error: samygo does not support CA_SET_DESCR_MODE");
224 ret = -1;
225 break;
228 if (ret > 0) // send() may return larger than 1
229 ret = 1;
231 #if defined(__powerpc__)
232 // Old dm500 boxes (ppc old) are using broken kernel, se we need some fixups
233 switch (request)
235 case DMX_STOP:
236 case CA_SET_DESCR:
237 case CA_SET_PID:
238 ret = 1;
240 #endif
241 // FIXME: Workaround for su980 bug
242 // See: http://www.streamboard.tv/wbb2/thread.php?postid=533940
243 if(boxtype_is("su980"))
244 ret = 1;
245 va_end(args);
246 return ret;
249 // tunemm_caid_map
250 #define FROM_TO 0
251 #define TO_FROM 1
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;
256 #else
257 int32_t pausecam = 0, disable_pmt_files = 0, pmt_stopmarking = 0;
258 #endif
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 },
279 #ifdef WITH_STAPI5
280 /* sh4 (stapi5)*/ { "/dev/stapi/", "stpti5_ioctl", "stpti5_ioctl", "/tmp/camd.socket", STAPI },
281 #else
282 /* sh4 (stapi)*/ { "/dev/stapi/", "stpti4_ioctl", "stpti4_ioctl", "/tmp/camd.socket", STAPI },
283 #endif
284 /* coolstream*/ { "/dev/cnxt/", "null", "null", "/tmp/camd.socket", COOLAPI },
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);
303 struct s_emm_filter
305 int32_t demux_id;
306 uchar filter[32];
307 uint16_t caid;
308 uint32_t provid;
309 uint16_t pid;
310 uint32_t num;
311 struct timeb time_started;
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)))
331 { return 0; }
333 filter_item->demux_id = demux_id;
334 memcpy(filter_item->filter, filter, 32);
335 filter_item->caid = caid;
336 filter_item->provid = provid;
337 filter_item->pid = emmpid;
338 filter_item->num = num;
339 if (enable)
341 cs_ftime(&filter_item->time_started);
343 else
345 memset(&filter_item->time_started, 0, sizeof(filter_item->time_started));
348 if(num > 0)
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);
354 else if(num < 0)
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);
360 else
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);
366 return 1;
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;
372 LL_ITER itr;
373 if(ll_count(ll) > 0)
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))
379 { return 1; }
382 return 0;
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))
397 { return 1; }
398 if(is_emmfilter_in_list_internal(ll_emm_inactive_filter, filter, emmpid, provid, caid))
399 { return 1; }
400 if(is_emmfilter_in_list_internal(ll_emm_pending_filter, filter, emmpid, provid, caid))
401 { return 1; }
403 return 0;
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;
409 LL_ITER itr;
410 if(ll_count(ll) > 0)
412 itr = ll_iter_create(ll);
413 while((filter = ll_iter_next(&itr)))
415 if(filter->demux_id == demux_id && filter->num == num)
416 { return filter; }
419 return NULL;
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);
435 if(emm_filter)
436 { return emm_filter; }
437 emm_filter = get_emmfilter_by_filternum_internal(ll_emm_inactive_filter, demux_id, num);
438 if(emm_filter)
439 { return emm_filter; }
440 emm_filter = get_emmfilter_by_filternum_internal(ll_emm_pending_filter, demux_id, num);
441 if(emm_filter)
442 { return emm_filter; }
444 return NULL;
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;
450 LL_ITER itr;
451 if(ll_count(ll) > 0)
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);
459 return 1;
463 return 0;
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))
469 { return; }
470 if(ll_emm_inactive_filter && remove_emmfilter_from_list_internal(ll_emm_inactive_filter, demux_id, caid, provid, pid, num))
471 { return; }
472 if(ll_emm_pending_filter && remove_emmfilter_from_list_internal(ll_emm_pending_filter, demux_id, caid, provid, pid, num))
473 { return; }
476 void dvbapi_net_add_str(unsigned char *packet, int *size, const char *str)
478 unsigned char *str_len = &packet[*size]; //string length
479 *size += 1;
481 *str_len = snprintf((char *) &packet[*size], DVBAPI_MAX_PACKET_SIZE - *size, "%s", str);
482 *size += *str_len;
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
488 int32_t size = 0;
489 uint32_t u32;
491 // not connected?
492 if (socket_fd <= 0)
493 return 0;
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
502 u32 = htonl(msgid);
503 memcpy(&packet[size], &u32, 4);
504 size += 4;
507 // type of request
508 u32 = request;
509 if (client_proto_version >= 1)
510 u32 = htonl(u32);
511 memcpy(&packet[size], &u32, 4);
512 size += 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
518 // struct with data
519 switch (request)
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);
526 size += 2;
528 unsigned char *info_len = &packet[size]; //info string length
529 size += 1;
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);
537 size += *info_len;
538 break;
540 case DVBAPI_ECM_INFO:
542 if (er->rc >= E_NOTFOUND)
543 return 0;
545 int8_t hops = 0;
547 uint16_t sid = htons(er->srvid); //service ID (program number)
548 memcpy(&packet[size], &sid, 2);
549 size += 2;
551 uint16_t caid = htons(er->caid); //CAID
552 memcpy(&packet[size], &caid, 2);
553 size += 2;
555 uint16_t pid = htons(er->pid); //PID
556 memcpy(&packet[size], &pid, 2);
557 size += 2;
559 uint32_t prid = htonl(er->prid); //Provider ID
560 memcpy(&packet[size], &prid, 4);
561 size += 4;
563 uint32_t ecmtime = htonl(client->cwlastresptime); //ECM time
564 memcpy(&packet[size], &ecmtime, 4);
565 size += 4;
567 dvbapi_net_add_str(packet, &size, get_cardsystem_desc_by_caid(er->caid)); //cardsystem name
569 switch (er->rc)
571 case E_FOUND:
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
577 else
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;
582 break;
584 case E_CACHE1:
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
588 break;
590 case E_CACHE2:
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
594 break;
596 case E_CACHEEX:
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
600 break;
603 packet[size++] = hops; //hops
605 break;
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;
620 break;
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;
635 break;
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;
651 break;
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);
670 size += 2;
672 memcpy(&packet[size], fp->filter.filter, 16);
673 size += 16;
674 memcpy(&packet[size], fp->filter.mask, 16);
675 size += 16;
676 memcpy(&packet[size], fp->filter.mode, 16);
677 size += 16;
679 uint32_t timeout = htonl(fp->timeout);
680 memcpy(&packet[size], &timeout, 4);
681 size += 4;
683 uint32_t flags = htonl(fp->flags);
684 memcpy(&packet[size], &flags, 4);
685 size += 4;
687 else
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);
699 size += 2;
701 else
703 uint16_t pid = demux[demux_index].demux_fd[filter_number].pid;
704 packet[size++] = pid >> 8;
705 packet[size++] = pid & 0xff;
708 break;
710 default: //unknown request
712 cs_log("ERROR: dvbapi_net_send: invalid request");
713 return 0;
717 // sending
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
722 return 0;
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++) { ; }
732 if(i >= maxfilter)
734 cs_log_dbg(D_DVBAPI, "no free filter");
735 return -1;
737 n = i;
739 if(USE_OPENXCAS)
741 if(type == TYPE_ECM)
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
754 return 1;
757 switch(api)
759 case DVBAPI_3:
760 if (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
761 ret = filterfd = DUMMY_FD;
762 else
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));
769 sFP2.pid = pid;
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);
794 else
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);
800 else
801 ret = dvbapi_ioctl(filterfd, DMX_SET_FILTER, &sFP2);
803 break;
805 case DVBAPI_1:
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));
812 sFP1.pid = pid;
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);
819 break;
820 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
821 case STAPI:
822 ret = filterfd = stapi_set_filter(demux_id, pid, filt, mask, n, demux[demux_id].pmt_file);
823 if(ret <= 0)
825 ret = -1; // error setting filter!
827 break;
828 #endif
829 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
830 case COOLAPI:
831 ret = filterfd = coolapi_open_device(demux[demux_id].demux_index, demux_id);
832 if(ret > 0)
834 ret = coolapi_set_filter(filterfd, n, pid, filt, mask, type);
836 else
838 ret = -1; // fail
840 break;
841 #endif
842 default:
843 break;
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);
861 else
863 cs_log("ERROR: Could not start demux filter (api: %d errno=%d %s)", selected_api, errno, strerror(errno));
866 return ret;
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");
877 return 1;
878 #else
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);
886 else
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);
890 return 1;
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");
899 return 1;
901 else
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");
910 LL_ITER itr;
912 struct s_open_fd
914 uint32_t 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);
926 filtercount = 0;
927 while((dmx_fd = open(device_path, O_RDWR | O_NONBLOCK)) > 0 && filtercount < MAX_FILTER)
929 filtercount++;
930 if(!cs_malloc(&open_fd, sizeof(struct s_open_fd)))
932 close(dmx_fd);
933 break;
935 open_fd->fd = dmx_fd;
936 ll_append(ll_max_fd, open_fd);
939 if(filtercount > 0)
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);
952 devnum = i;
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.");
963 return 0;
965 #endif
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; }
982 #endif
983 return 1;
986 static int32_t dvbapi_read_device(int32_t dmx_fd, unsigned char *buf, uint32_t length)
988 int32_t readed;
989 uint32_t count = 0;
990 struct pollfd pfd[1];
992 pfd[0].fd = dmx_fd;
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
1010 count += readed;
1012 if(readed == 0 && count > 0) // nothing to read left
1014 break;
1017 else return -1; // other events than pollin/pri means bad news -> abort!
1019 else break;
1021 cs_log_dump_dbg(D_TRACE, buf, count, "Received:");
1022 return count;
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)
1032 return DUMMY_FD;
1034 if(type == 0)
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);
1041 else
1043 if(cfg.dvbapi_boxtype == BOXTYPE_DUCKBOX || cfg.dvbapi_boxtype == BOXTYPE_DBOX2 || cfg.dvbapi_boxtype == BOXTYPE_UFS910)
1044 { ca_offset = 1; }
1046 if(cfg.dvbapi_boxtype == BOXTYPE_QBOXHD)
1047 { num = 0; }
1049 if(cfg.dvbapi_boxtype == BOXTYPE_PC)
1050 { num = 0; }
1052 if(cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
1053 { num = 0; }
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) {
1063 if(type == 0)
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));
1071 if (ret < 0)
1072 { close(dmx_fd); }
1074 else if(type == 1)
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));
1085 if(ret < 0)
1086 { close(dmx_fd); }
1087 cs_log_dbg(D_DVBAPI, "NET DEVICE open (port = %d) fd %d", udp_port + adapter, dmx_fd);
1089 else
1091 ret = -1;
1093 } else {
1094 dmx_fd = ret = open(device_path, O_RDWR | O_NONBLOCK);
1097 if(ret < 0)
1099 cs_log("ERROR: Can't open device %s (errno=%d %s)", device_path, errno, strerror(errno));
1100 return -1;
1103 cs_log_dbg(D_DVBAPI, "Open device %s (fd %d)", device_path, dmx_fd);
1105 return dmx_fd;
1108 uint16_t tunemm_caid_map(uint8_t direct, uint16_t caid, uint16_t srvid)
1110 int32_t i;
1111 struct s_client *cl = cur_client();
1112 TUNTAB *ttab = &cl->ttab;
1114 if (!ttab->ttnum)
1115 return caid;
1117 if(direct)
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; }
1126 else
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; }
1135 return caid;
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) {
1143 return 1;
1145 #endif
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)
1155 error = 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;
1165 if(USE_OPENXCAS)
1167 demux[demux_index].demux_fd[num].type = 0;
1168 demux[demux_index].demux_fd[num].fd = 0;
1169 return 1; // all ok!
1172 if(fd > 0)
1176 errno = 0;
1177 if(try)
1179 cs_sleepms(50);
1181 try++;
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)
1188 case DVBAPI_3:
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);
1191 else
1192 retfilter = dvbapi_ioctl(fd, DMX_STOP, NULL);
1193 break;
1195 case DVBAPI_1:
1196 retfilter = dvbapi_ioctl(fd, DMX_STOP, NULL);
1197 break;
1199 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
1200 case STAPI:
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
1204 retfilter = -1;
1206 break;
1207 #endif
1208 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
1209 case COOLAPI:
1210 retfilter = coolapi_remove_filter(fd, num);
1211 if(retfilter >=0 )
1213 retfd = coolapi_close_device(fd);
1215 break;
1216 #endif
1217 default:
1218 break;
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!
1224 try = 0;
1227 if(try)
1229 errno = 0;
1230 cs_sleepms(50);
1232 try++;
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!
1239 else
1241 flush_read_fd(demux_index, num, fd); // flush filter input buffer in attempt to avoid overflow receivers internal buffer
1242 retfd = close(fd);
1243 if(errno == 9) { retfd = 0; } // no error on bad file descriptor
1246 else
1247 retfd = 0;
1249 } while (retfd < 0 && try < 10);
1250 #endif
1252 else // fd <=0
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));
1260 return retfilter;
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));
1267 return retfd;
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)
1280 int32_t z;
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
1288 int32_t i;
1289 for(i = 0; i < demux[demux_index].STREAMpidcount; i++)
1291 int8_t match = 0;
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
1314 int32_t y;
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
1334 if(!match)
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);
1341 break;
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)
1363 int32_t o;
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
1373 return;
1376 uchar filter[32];
1377 memset(filter, 0, 32);
1379 filter[0] = table;
1380 filter[16] = mask;
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.
1396 // Don't use it
1397 return;
1398 #endif
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.
1407 // Don't use it
1408 return;
1409 #endif
1411 uchar filter[16], mask[16];
1412 memset(filter, 0, 16);
1413 memset(mask, 0, 16);
1415 filter[0] = 0x02;
1416 i2b_buf(2, demux[demux_index].program_number, filter + 1); // add srvid to filter since the pid can deliver pmt for multiple srvid
1417 mask[0] = 0xFF;
1418 mask[1] = 0xFF;
1419 mask[2] = 0xFF;
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)
1425 unsigned int j;
1426 if(!demux[demux_index].EMMpidcount)
1427 { return; }
1429 //if (demux[demux_index].emm_filter)
1430 // return;
1433 struct s_csystem_emm_filter *dmx_filter = NULL;
1434 unsigned int filter_count = 0;
1435 uint16_t caid, ncaid;
1436 uint32_t provid;
1438 struct s_reader *rdr = NULL;
1439 struct s_client *cl = cur_client();
1440 if(!cl || !cl->aureader_list)
1441 { return; }
1443 LL_ITER itr = ll_iter_create(cl->aureader_list);
1444 while((rdr = ll_iter_next(&itr)))
1446 if(!(rdr->grp & cl->grp))
1447 { continue; }
1448 if(rdr->audisabled || !rdr->enable || (!is_network_reader(rdr) && rdr->card_status != CARD_INSERTED))
1449 { continue; }
1451 const struct s_cardsystem *csystem;
1452 uint16_t c, match;
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;
1457 if(!caid) continue;
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;
1464 if (caid == ncaid)
1466 match = emm_reader_match(rdr, caid, provid);
1468 else
1470 match = emm_reader_match(rdr, ncaid, provid);
1472 if(match)
1474 csystem = get_cardsystem_by_caid(caid);
1475 if(csystem)
1477 if(caid != ncaid)
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);
1485 else
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);
1488 continue;
1491 else if (csystem->get_emm_filter)
1493 csystem->get_emm_filter(rdr, &dmx_filter, &filter_count);
1496 else
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);
1499 continue;
1502 for(j = 0; j < filter_count ; j++)
1504 if(dmx_filter[j].enabled == 0)
1505 { continue; }
1507 uchar filter[32];
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);
1517 continue;
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);
1523 continue;
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);
1531 else
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);
1539 filter_count = 0;
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)))
1560 added = 1;
1561 if(stream >-1)
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);
1567 continue;
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);
1575 if(added == 1)
1576 { return; }
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);
1582 return;
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))
1619 { continue; }
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)
1628 char typetext[40];
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;
1642 uint16_t i;
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);
1652 return;
1655 if(i < ECM_PIDS)
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);
1665 else
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;
1679 #else
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; }
1690 else
1691 { demux[demux_id].max_emm_filter = maxfilter - ecm_filter_needed; }
1693 else
1695 demux[demux_id].max_emm_filter = maxfilter - 1;
1697 #endif
1698 uint16_t i, k;
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;
1710 switch(caid >> 8)
1712 case 0x01:
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);
1720 break;
1721 case 0x05:
1722 for(k = i + 6; k < i + buf[i + 1] + 2; k += buf[k + 1] + 2)
1724 if (buf[k] == 0x14)
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);
1730 break;
1731 case 0x18:
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);
1740 else
1742 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, 0, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1744 break;
1745 case 0x27:
1746 case 0x4A:
1748 if(caid_is_bulcrypt(caid))
1750 dvbapi_add_emmpid(demux_id, caid, emm_pid, 0, 0, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1751 break;
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);
1759 else
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);
1768 break;
1769 default:
1770 dvbapi_add_emmpid(demux_id, caid, emm_pid, 0, 0, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1771 break;
1774 return;
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;
1782 ca_index_t idx = 0;
1783 uint32_t tmp_idx;
1785 if(cfg.dvbapi_boxtype == BOXTYPE_NEUMO)
1787 tmp_idx = 0;
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)
1796 fail = 0;
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)
1812 fail = 1;
1813 idx++;
1820 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
1822 if(idx > INDEX_MAX_NET)
1824 idx = INDEX_INVALID;
1827 else
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!
1837 return idx;
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;
1845 ca_pid_t ca_pid2;
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)
1852 case STAPI:
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!!!
1855 break;
1856 #endif
1857 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
1858 case COOLAPI:
1859 break;
1860 #endif
1861 default:
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;
1868 if(enable){
1869 action = update_streampid_list(i, streampid, curidx, use_des);
1871 if(!enable){
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);
1916 else
1918 currentfd = ca_fd[i];
1919 if(currentfd <= 0)
1921 currentfd = dvbapi_open_device(1, i, demux[demux_id].adapter_index);
1922 ca_fd[i] = currentfd; // save fd of this ca
1924 if(currentfd > 0)
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;
1945 break;
1947 return;
1950 void dvbapi_stop_all_descrambling(uint32_t msgid)
1952 int32_t j;
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)
1962 int32_t j;
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)
1975 int32_t i, j, z;
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;
1995 // disable streams!
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);
2021 return;
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;
2028 ECM_REQUEST *er;
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)
2036 if((p->type != 'p')
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))
2043 { continue; }
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;
2051 else
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!
2059 else
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
2067 er->chid = 0;
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;
2079 er->msgid = msgid;
2081 #ifdef WITH_STAPI5
2082 cs_strncpy(er->dev_name, dev_list[demux[demux_id].dev_index].name, sizeof(dev_list[demux[demux_id].dev_index].name));
2083 #endif
2085 struct timeb now;
2086 cs_ftime(&now);
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,
2094 (int)(gone/1000));
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))
2115 int32_t j, n;
2116 er->ecmlen = 5;
2117 er->ecm[0] = 0x80; // to pass the cache check it must be 0x80 or 0x81
2118 er->ecm[1] = 0x00;
2119 er->ecm[2] = 0x02;
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);
2125 er->ecm[2] += 2;
2126 er->ecmlen += 2;
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);
2137 started = 1;
2139 request_cw(dvbapi_client, er, demux_id, 0); // do not register ecm since this try!
2140 fake_ecm = 1;
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);
2157 else
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);
2168 started = 1;
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); }
2181 return started;
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;
2187 int32_t i;
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;
2195 break;
2199 if(!ecm_pid)
2200 { return NULL; }
2202 for(p = dvbapi_priority; p != NULL; p = p->next)
2204 if(p->type != type
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)))
2211 { continue; }
2212 return p;
2214 return NULL;
2217 struct s_dvbapi_priority *dvbapi_check_prio_match(int32_t demux_id, int32_t pidindex, char type)
2219 if(!dvbapi_priority)
2221 return NULL;
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)
2228 if(p->type != type
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))
2235 { continue; }
2236 return p;
2238 return NULL;
2241 void dvbapi_process_emm(int32_t demux_index, int32_t filter_num, unsigned char *buffer, uint32_t len)
2243 EMM_PACKET epg;
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
2247 if(!filter)
2249 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d no filter matches -> SKIP!", demux_index, filter_num +1);
2250 return;
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');
2257 if(mapentry)
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);
2276 if(caid != ncaid)
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)
2288 FILE *fp;
2289 char token[128], str1[128];
2290 char type;
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");
2297 if(!fp)
2299 cs_log_dbg(D_DVBAPI, "ERROR: Can't open priority file %s", token);
2300 return;
2303 if(dvbapi_priority)
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)
2309 o = p->next;
2310 NULLFREE(p);
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')
2319 { continue; }
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
2326 { continue; }
2328 for(i = 0; i < (int)strlen(token); i++)
2330 if(token[i] == '@')
2332 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] == '/')
2345 token[i] = '\0';
2346 break;
2350 type = 0;
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);
2354 #else
2355 ret = sscanf(trim(token), "%c: %63s %63s", &type, str1, str1 + 64);
2356 #endif
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);
2367 continue;
2370 struct s_dvbapi_priority *entry;
2371 if(!cs_malloc(&entry, sizeof(struct s_dvbapi_priority)))
2373 ret = fclose(fp);
2374 if(ret < 0) { cs_log("ERROR: Could not close oscam.dvbapi fd (errno=%d %s)", errno, strerror(errno)); }
2375 return;
2378 entry->type = type;
2379 entry->next = NULL;
2381 count++;
2383 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
2384 if(type == 's')
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;
2398 else
2400 struct s_dvbapi_priority *p;
2401 for(p = dvbapi_priority; p->next != NULL; p = p->next) { ; }
2402 p->next = entry;
2404 continue;
2406 #endif
2408 char c_srvid[34];
2409 c_srvid[0] = '\0';
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);
2413 if(ret < 1)
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!
2419 else
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);
2425 entry->caid = caid;
2426 entry->provid = provid;
2427 entry->ecmpid = ecmpid;
2428 entry->chid = chid;
2429 entry->cadata = cadata;
2431 uint32_t delay = 0, force = 0, mapcaid = 0, mapprovid = 0, mapecmpid = 0, pidx = 0;
2432 switch(type)
2434 case 'i':
2435 ret = sscanf(str1 + 64, "%1d", &pidx);
2436 entry->pidx = pidx+1;
2437 if(ret < 1) entry->pidx = 0;
2438 break;
2439 case 'd':
2440 sscanf(str1 + 64, "%4d", &delay);
2441 entry->delay = delay;
2442 break;
2443 case 'l':
2444 entry->delay = dyn_word_atob(str1 + 64);
2445 if(entry->delay == -1) { entry->delay = 0; }
2446 break;
2447 case 'p':
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;
2452 break;
2453 case 'm':
2454 sscanf(str1 + 64, "%4x:%6x", &mapcaid, &mapprovid);
2455 if(!mapcaid) { mapcaid = 0xFFFF; }
2456 entry->mapcaid = mapcaid;
2457 entry->mapprovid = mapprovid;
2458 break;
2459 case 'a':
2460 case 'j':
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;
2466 break;
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)))
2480 { continue; }
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;
2489 else
2491 struct s_dvbapi_priority *p;
2492 for(p = dvbapi_priority; p->next != NULL; p = p->next) { ; }
2493 p->next = entry2;
2497 NULLFREE(entry);
2498 continue;
2500 else
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;
2511 else
2513 struct s_dvbapi_priority *p;
2514 for(p = dvbapi_priority; p->next != NULL; p = p->next) { ; }
2515 p->next = entry;
2519 cs_log_dbg(D_DVBAPI, "Read %d entries from %s", count, cs_prio);
2521 ret = fclose(fp);
2522 if(ret < 0) { cs_log("ERROR: Could not close oscam.dvbapi fd (errno=%d %s)", errno, strerror(errno)); }
2523 return;
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;
2531 cs_ftime(&start);
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!
2560 ECM_REQUEST *er;
2561 if(!cs_malloc(&er, sizeof(ECM_REQUEST)))
2562 { return; }
2564 for(prio = dvbapi_priority; prio != NULL; prio = prio->next)
2566 if(prio->type != 'p' && prio->type != 'i' )
2567 { continue; }
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; }
2592 if(prio->force)
2594 int32_t j;
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);
2606 NULLFREE(er);
2607 return; // go start descrambling since its forced by user!
2609 else
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--;
2614 matching_done = 1;
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!
2638 int32_t nr;
2639 SIDTAB *sidtab;
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);
2647 if(btun_caid)
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
2668 else
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);
2713 if(btun_caid)
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);
2770 if(btun_caid)
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++;}
2783 anyreader++;
2784 continue;
2786 if(cacheex_reader(rdr))
2788 demux[demux_index].ECMpids[n].status += cacheexprio;
2789 count_matching_cacheex_reader++;
2790 cacheexprio=1;
2792 if(is_localreader(rdr, er))
2794 demux[demux_index].ECMpids[n].status += localprio;
2795 count_matching_local_reader++;
2796 localprio=1;
2801 if(oldstatus != demux[demux_index].ECMpids[n].status)
2803 if(anyreader)
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);
2808 else
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
2825 if(c != NULL)
2827 found = n;
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);
2833 break;
2837 if(found == -1)
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);
2845 if(c != NULL)
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!
2880 if(n != found)
2882 // disable non matching pid
2883 demux[demux_index].ECMpids[n].status = -1;
2885 else
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);
2895 NULLFREE(er);
2897 cs_ftime(&end);
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);
2900 return;
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;
2907 uint32_t j, u, k;
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",
2916 if(info_length < 1)
2917 { return; }
2919 if((buffer[0] < skip_border) && info_length > 0) // skip input values like 0x00 and 0x01
2921 buffer++;
2922 info_length--;
2925 for(j = 0; j + 1 < info_length; j += descriptor_length + 2)
2927 descriptor_length = buffer[j + 1];
2929 if(is_audio)
2931 if(buffer[j] == 0x6A || buffer[j] == 0x73 || buffer[j] == 0x81)
2933 *is_audio = 1;
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)
2941 *is_audio = 1;
2942 break;
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);
2985 else
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);
3009 // Apply mapping:
3010 if(dvbapi_priority)
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');
3016 if(mapentry)
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)
3030 if(!er)
3032 return;
3036 int32_t filternum = dvbapi_set_section_filter(demux_id, er, -1); // set ecm filter to odd -> even and visaversa
3037 if(filternum < 0)
3039 cs_log_dbg(D_DVBAPI, "Demuxer %d not requesting cw -> ecm filter was killed!", demux_id);
3040 NULLFREE(er);
3041 return;
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!
3048 else
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);
3057 NULLFREE(er);
3058 return;
3060 else
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);
3070 NULLFREE(er);
3071 return;
3073 else
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);
3087 get_cw(client, er);
3089 #ifdef WITH_DEBUG
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);
3093 #endif
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)
3112 found = n;
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);
3131 return;
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)
3141 // enigma2
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;
3194 int32_t j = 0;
3195 int32_t demux_id = -1;
3196 uint16_t demux_index, adapter_index, pmtpid;
3197 uint32_t ca_mask;
3198 uint32_t program_number, program_info_length;
3199 uint8_t program_info_start = is_real_pmt ? 12 : 6;
3201 if(!is_real_pmt)
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;
3213 #else
3214 int32_t ca_pmt_list_management = buffer[0];
3215 #endif
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)
3246 full_check = 0;
3248 if (full_check)
3249 matched = (connfd > 0 && demux[i].socket_fd == connfd) && demux[i].program_number == program_number;
3250 else
3251 matched = connfd > 0 && demux[i].program_number == program_number;
3253 if(matched)
3255 if (full_check) {
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);
3264 demux_id = i;
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
3287 if(demux_id == -1)
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;
3303 if(pmtfile)
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
3309 if(pmtpid)
3311 dvbapi_start_pmt_filter(demux_id, pmtpid);
3313 else
3315 dvbapi_start_pat_filter(demux_id);
3317 break;
3322 if(demux_id >= MAX_DEMUX)
3324 cs_log("ERROR: No free id (MAX_DEMUX)");
3325 return -1;
3328 if(demux[demux_id].running == 0) demux[demux_id].ECMpidcount = 0; // reset number of ecmpids only if it was not running!
3330 else // is_real_pmt
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,
3372 es_info_length);
3374 // find and register videopid
3375 if(!vpid &&
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;
3389 stream_type = 0x03;
3391 else if(!vpid && stream_type == 0x80 && !is_audio)
3393 vpid = elementary_pid;
3396 else
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))
3404 { continue; }
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)");
3408 break;
3414 if(!is_real_pmt)
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++;
3431 vpid = pmtpid;
3434 else
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)
3457 unassoc_fd[j] = 0;
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))
3474 { continue; }
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++)
3479 { ; }
3481 if(xtra_demux_id >= MAX_DEMUX)
3483 cs_log("Found no free demux device for xtra streams.");
3484 continue;
3486 // copy to new demuxer
3487 if(!is_real_pmt)
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);
3523 else
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;
3537 --k;
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;
3547 --j;
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);
3583 cs_sleepms(1);
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) {
3605 DoNotStartEMM = 1;
3607 #endif
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!
3620 return demux_id;
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;
3627 char *tmpbuf;
3628 const unsigned char *ptr_in;
3629 unsigned char *ptr_out;
3630 size_t in_bytes, out_bytes;
3632 if(sourcelen == 0)
3634 buf[0] = '\0';
3635 return 1;
3638 if(!cs_malloc(&tmpbuf, buflen))
3640 return 0;
3643 if((sourcelen + 1) > buflen)
3644 { sourcelen = buflen - 1; }
3646 if(sourcelen > 0 && source[0] < 0x20)
3648 //ISO-8859
3649 if(source[0] >= 0x01 && source[0] <= 0x0B && source[0] != 0x08)
3650 { offset = 1; iso_mode = 4+source[0]; }
3652 //ISO-8859
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]; }
3657 //Unicode
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)
3665 //Unicode as UTF-8
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
3672 else
3673 { NULLFREE(tmpbuf); return 0; }
3676 if(offset >= sourcelen)
3677 { NULLFREE(tmpbuf); return 0; }
3679 if(iso_mode >= -1)
3681 for(i=0, j=0; i<(sourcelen-offset); i++)
3683 if(((uint8_t)source[offset+i]) >= 0x80 && ((uint8_t)source[offset+i]) <= 0x9F)
3685 continue;
3688 tmpbuf[j] = source[offset+i];
3689 j++;
3691 tmpbuf[j] = '\0';
3694 ptr_in = (const unsigned char *)tmpbuf;
3695 in_bytes = strlen(tmpbuf);
3696 ptr_out = (unsigned char *)buf;
3697 out_bytes = buflen;
3699 #ifdef READ_SDT_CHARSETS
3700 if(iso_mode >= -1)
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: ");
3707 if(iso_mode == -1)
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");
3712 NULLFREE(tmpbuf);
3713 return 0;
3716 else
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");
3721 NULLFREE(tmpbuf);
3722 return 0;
3726 #else
3727 if(iso_mode >= -1)
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!");
3732 #endif
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");
3743 NULLFREE(tmpbuf);
3744 return 0;
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: ");
3758 NULLFREE(tmpbuf);
3759 return 1;
3762 static void dvbapi_create_srvid_line(int32_t demux_id, char *buffer, uint32_t buflen)
3764 int32_t i, j;
3765 uint16_t caid_done[32], cur_caid;
3766 uint8_t caid_done_count = 0, skip_caid;
3767 int32_t pos = 0;
3769 if(demux[demux_id].ECMpidcount == 0)
3771 snprintf(buffer, buflen, "%04X@%06X", NO_CAID_VALUE, NO_PROVID_VALUE);
3772 return;
3775 for(i=0; i < demux[demux_id].ECMpidcount && i < 32; i++)
3777 skip_caid = 0;
3779 for(j=0; j < caid_done_count; j++)
3781 if(caid_done[j] == demux[demux_id].ECMpids[i].CAID)
3783 skip_caid = 1;
3784 break;
3788 if(skip_caid)
3790 continue;
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)
3800 continue;
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;
3810 caid_done_count++;
3814 static const char *dvbapi_get_service_type(uint8_t service_type_id)
3816 switch(service_type_id)
3818 case 0x01:
3819 case 0x11:
3820 default:
3821 return "TV";
3823 case 0x02:
3824 case 0x07:
3825 case 0x0A:
3826 return "Radio";
3828 case 0x03:
3829 return "Teletext";
3831 case 0x0C:
3832 return "Data";
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;
3842 int32_t pidindex;
3843 char provider_name[64], service_name[64], tmp[256], srvid_line[1024];
3844 const char *type;
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: ");
3850 if(length < 3)
3851 { return; }
3853 if(buffer[0] != 0x42)
3854 { return; }
3856 section_length = b2i(2, buffer + 1) &0xFFF;
3858 if(section_length+3 != length)
3859 { return; }
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)
3867 { return; }
3869 pos += 5;
3871 if(service_id != demux[demux_id].program_number)
3872 { continue; }
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)
3880 { break; }
3882 if(tag != 0x48)
3883 { continue; }
3885 if(dpos+3 >= descriptor_length)
3886 { break; }
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)
3892 { break; }
3894 service_name_length = buffer[pos+dpos+4+provider_name_length];
3895 if((dpos+4+provider_name_length+1+service_name_length) > descriptor_length)
3896 { break; }
3898 pidindex = demux[demux_id].pidindex;
3900 if (pidindex !=-1)
3902 provid = demux[demux_id].ECMpids[pidindex].PROVID;
3903 caid = demux[demux_id].ECMpids[pidindex].CAID;
3905 else
3907 if(demux[demux_id].ECMpidcount == 0 || demux[demux_id].ECMpids[0].CAID == 0)
3909 caid = NO_CAID_VALUE;
3910 provid = NO_PROVID_VALUE;
3912 else
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))
3920 { break; }
3922 if(!dvbapi_extract_sdt_string(service_name, sizeof(service_name), buffer+pos+dpos+4+provider_name_length+1, service_name_length))
3923 { break; }
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));
3933 if(tmp[0] == '\0')
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);
3940 fclose(fpsave);
3942 init_provid();
3947 if(strlen(service_name))
3949 get_servicename_or_null(cur_client(), service_id, provid, caid, tmp, sizeof(tmp));
3951 if(tmp[0] == '\0')
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); }
3965 else
3966 { fprintf(fpsave, "\n%04X:%s|%s|%s", service_id, srvid_line, service_name, type); }
3968 did_save_srvid = 1;
3971 else
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); }
3984 else
3985 { fprintf(fpsave, "\n%s:%04X||%s|%s", srvid_line, service_id, service_name, type); }
3987 did_save_srvid = 1;
3992 if(fpsave)
3993 { fclose(fpsave); }
3995 if(did_save_srvid)
3996 { init_srvid(); }
4000 return;
4005 static void dvbapi_parse_pat(int32_t demux_id, unsigned char *buffer, uint32_t length, uint32_t msgid)
4007 uint16_t srvid;
4008 uint32_t i;
4010 dvbapi_stop_filter(demux_id, TYPE_PAT, msgid);
4012 for(i=8; i+7<length; i+=4)
4014 srvid = b2i(2, buffer+i);
4016 if(srvid == 0)
4017 { continue; }
4019 if(demux[demux_id].program_number == srvid)
4021 dvbapi_start_pmt_filter(demux_id, b2i(2, buffer+i+2) & 0x1FFF);
4022 break;
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))
4038 { return 0; }
4039 if((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
4040 { return 0; }
4041 if(bind(listenfd, (struct sockaddr *)&servaddr, clilen) < 0)
4042 { return 0; }
4043 if(listen(listenfd, 5) < 0)
4044 { return 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);
4051 return listenfd;
4054 int32_t dvbapi_net_init_listenfd(void)
4056 int32_t listenfd;
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)
4065 { return 0; }
4067 int32_t opt = 0;
4068 #ifdef IPV6SUPPORT
4070 // azbox toolchain do not have this define
4071 #ifndef IPV6_V6ONLY
4072 #define IPV6_V6ONLY 26
4073 #endif
4075 // set the server socket option to listen on IPv4 and IPv6 simultaneously
4076 setsockopt(listenfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&opt, sizeof(opt));
4077 #endif
4079 opt = 1;
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)
4084 { return 0; }
4085 if(listen(listenfd, 5) < 0)
4086 { return 0; }
4088 return listenfd;
4091 static pthread_mutex_t event_handler_lock = PTHREAD_MUTEX_INITIALIZER;
4093 void event_handler(int32_t UNUSED(signal))
4095 struct stat pmt_info;
4096 char dest[1024];
4097 DIR *dirp;
4098 struct dirent entry, *dp = NULL;
4099 int32_t i, pmt_fd;
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)
4106 { pausecam = 0; }
4107 else
4109 int32_t standby_fd = open(STANDBY_FILE, O_RDONLY);
4110 pausecam = (standby_fd > 0) ? 1 : 0;
4111 if(standby_fd > 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);
4121 return;
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);
4130 if(pmt_fd > 0)
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)); }
4136 continue;
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)); }
4146 continue;
4148 else
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);
4159 return;
4162 dirp = opendir(TMPDIR);
4163 if(!dirp)
4165 cs_log_dbg(D_DVBAPI, "opendir failed (errno=%d %s)", errno, strerror(errno));
4166 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4167 return;
4170 while(!cs_readdir_r(dirp, &entry, &dp))
4172 if(!dp) { break; }
4174 if(strlen(dp->d_name) < 7)
4175 { continue; }
4176 if(strncmp(dp->d_name, "pmt", 3) != 0 || strncmp(dp->d_name + strlen(dp->d_name) - 4, ".tmp", 4) != 0)
4177 { continue; }
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!
4186 if(p == NULL)
4188 cs_log_dbg(D_DVBAPI, "No matching S: line in oscam.dvbapi for pmtfile %s -> skip!", dp->d_name);
4189 continue;
4191 #endif
4192 snprintf(dest, sizeof(dest), "%s%s", TMPDIR, dp->d_name);
4193 pmt_fd = open(dest, O_RDONLY);
4194 if(pmt_fd < 0)
4195 { continue; }
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)); }
4201 continue;
4204 int32_t found = 0;
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)
4211 found = 1;
4212 break;
4216 if(found)
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)); }
4220 continue;
4223 cs_log_dbg(D_DVBAPI, "found pmt file %s", dest);
4224 cs_sleepms(100);
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)); }
4230 if(len < 1)
4232 cs_log_dbg(D_DVBAPI, "pmt file %s have invalid len!", dest);
4233 continue;
4236 int32_t pmt_id;
4238 #ifdef QBOXHD
4239 uint32_t j1, j2;
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");
4245 continue;
4248 for(j2 = 0, j1 = 0; j2 < len; j2 += 2, j1++)
4250 unsigned int tmp;
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);
4255 return;
4257 else
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);
4265 #else
4266 if(len > sizeof(dest))
4268 cs_log_dbg(D_DVBAPI, "event_handler() dest buffer is to small for pmt data!");
4269 continue;
4271 if(len < 16)
4273 cs_log_dbg(D_DVBAPI, "event_handler() received pmt is too small! (%d < 16 bytes!)", len);
4274 continue;
4276 cs_log_dump_dbg(D_DVBAPI, mbuf, len, "pmt:");
4278 dest[0] = 0x03;
4279 dest[1] = mbuf[3];
4280 dest[2] = mbuf[4];
4281 uint32_t pmt_program_length = b2i(2, mbuf + 10)&0xFFF;
4282 i2b_buf(2, pmt_program_length + 1, (uchar *) dest + 4);
4283 dest[6] = 0;
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);
4288 #endif
4290 if(pmt_id >= 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;
4299 break;
4302 closedir(dirp);
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__);
4311 while(!exit_oscam)
4313 cs_sleepms(750);
4314 event_handler(0);
4317 return NULL;
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);
4330 return;
4333 if(demux_id < 0 || demux_id >= MAX_DEMUX)
4335 cs_log("dvbapi_process_input(): error - received invalid demux_id (%d)", demux_id);
4336 return;
4339 if(filter_num < 0 || filter_num >= MAX_FILTER)
4341 cs_log("dvbapi_process_input(): error - received invalid filter_num (%d)", filter_num);
4342 return;
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)
4351 if(!filt_match)
4353 cs_log_dbg(D_DVBAPI,"Demuxer %d receiver returned data that was not matching to the filter -> delivered filter data discarded!", demux_id);
4354 return;
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
4363 curpid->table = 0;
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!
4372 return;
4375 if(filtertype == TYPE_ECM)
4377 uint32_t chid = 0x10000;
4378 ECM_REQUEST *er;
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);
4387 if(curpid)
4389 curpid->tries-=0x0E;
4391 return;
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]);
4397 if(curpid)
4399 curpid->tries--;
4401 return;
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()))
4409 return;
4412 er->srvid = demux[demux_id].program_number;
4414 #ifdef WITH_STAPI5
4415 cs_strncpy(er->dev_name, dev_list[demux[demux_id].dev_index].name, sizeof(dev_list[demux[demux_id].dev_index].name));
4416 #endif
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
4430 er->chid = chid;
4431 er->msgid = msgid;
4432 dvbapi_set_section_filter(demux_id, er, filter_num);
4433 NULLFREE(er);
4434 return;
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()))
4452 return;
4455 er->srvid = demux[demux_id].program_number;
4457 #ifdef WITH_STAPI5
4458 cs_strncpy(er->dev_name, dev_list[demux[demux_id].dev_index].name, sizeof(dev_list[demux[demux_id].dev_index].name));
4459 #endif
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);
4472 er->msgid = msgid;
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;
4480 if(!USE_OPENXCAS)
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;
4488 er->chid = chid;
4490 if(len == 0) // only used on receiver internal bufferoverflow to get quickly fresh ecm filterdata otherwise freezing!
4492 curpid->table = 0;
4493 dvbapi_set_section_filter(demux_id, er, filter_num);
4494 NULLFREE(er);
4495 return;
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
4511 NULLFREE(er);
4512 return;
4515 else //fix for receivers not supporting section filtering
4517 if(curpid->table == buffer[0]){
4518 NULLFREE(er);
4519 return;
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);
4524 else
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!
4548 NULLFREE(er);
4549 return;
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
4557 curpid->table = 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
4559 NULLFREE(er);
4560 return;
4562 else // all nonirdeto cas systems
4564 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match(demux_id, pid, 'p');
4565 curpid->table = 0;
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)
4569 NULLFREE(er);
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!
4579 NULLFREE(er);
4580 return;
4584 struct s_dvbapi_priority *p;
4586 for(p = dvbapi_priority; p != NULL; p = p->next)
4588 if(p->type != 'l'
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))
4593 { continue; }
4595 if((uint)p->delay == sctlen && p->force < 6)
4597 p->force++;
4598 NULLFREE(er);
4599 return;
4601 if(p->force >= 6)
4602 { p->force = 0; }
4605 if(!curpid->PROVID)
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)
4612 curpid->table = 0;
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
4614 NULLFREE(er);
4615 return;
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!
4621 if((p->type != 'i')
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))
4627 { continue; }
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;
4637 curpid->table = 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!
4652 NULLFREE(er);
4653 return;
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);
4671 return;
4674 else
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);
4686 return;
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))
4716 return -1;
4719 if(len == -1)
4721 return 0;
4724 return len;
4727 static uint16_t dvbapi_get_nbof_missing_header_bytes(uchar* mbuf, uint16_t mbuf_len)
4729 if(mbuf_len < 4)
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
4739 if(mbuf[3] & 0x80)
4741 uint32_t size = mbuf[3] & 0x7F;
4743 if(mbuf_len < (4+size))
4745 return (4+size) - mbuf_len;
4748 return 0;
4750 else switch (opcode)
4752 case DVBAPI_FILTER_DATA: // min 9 bytes
4754 if(mbuf_len < 9)
4756 return 9 - mbuf_len;
4758 return 0;
4760 case DVBAPI_CLIENT_INFO: // min 7 bytes
4762 if(mbuf_len < 7)
4764 return 7 - mbuf_len;
4766 return 0;
4768 default:
4770 return 0;
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;
4781 (*chunksize) = 0;
4782 (*data_len) = 0;
4784 if (client_proto_version >= 3)
4785 msgid_size = 5;
4787 if(mbuf_len < 4 + msgid_size)
4789 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short", mbuf_len);
4790 (*chunksize) = 1;
4791 (*data_len) = 1;
4792 return;
4795 mbuf += msgid_size;
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)
4802 uint32_t size = 0;
4804 if(mbuf[3] & 0x80)
4806 uint32_t tmp_data_len = 0;
4808 size = mbuf[3] & 0x7F;
4810 if(3 + size < mbuf_len)
4812 uint32_t k;
4813 for (k = 0; k < size; k++)
4815 tmp_data_len = (tmp_data_len << 8) | mbuf[4 + k];
4818 else
4820 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short for opcode %08X", mbuf_len, opcode);
4821 (*chunksize) = 1;
4822 (*data_len) = 1;
4823 return;
4826 if(tmp_data_len > 0xFFFF)
4828 cs_log("Socket command too big: %d bytes", tmp_data_len);
4829 (*data_len) = 0xFFFF - 4 - size;
4831 else
4833 (*data_len) = tmp_data_len;
4836 else
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
4849 if(mbuf_len < 9)
4851 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short for DVBAPI_FILTER_DATA", mbuf_len);
4852 (*chunksize) = 1;
4853 (*data_len) = 1;
4854 return;
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));
4861 break;
4863 case DVBAPI_CLIENT_INFO: // min 7 bytes
4865 if(mbuf_len < 7)
4867 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short for DVBAPI_CLIENT_INFO", mbuf_len);
4868 (*chunksize) = 1;
4869 (*data_len) = 1;
4870 return;
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));
4877 break;
4879 default:
4881 cs_log("Unknown socket command received: 0x%08X", opcode);
4882 (*chunksize) = 1;
4883 (*data_len) = 1;
4884 break;
4888 if((*chunksize) < 1)
4890 (*chunksize) = 1;
4891 (*data_len) = 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)
4899 uint32_t msgid = 0;
4900 if (*client_proto_version >= 3) {
4901 if (mbuf[0] != 0xa5) {
4902 cs_log("Error: network packet malformed! (no start)");
4903 return;
4905 msgid = b2i(4, mbuf + 1);
4906 mbuf += 5;
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:
4917 if(data_len < 5)
4919 cs_log("Error: packet DVBAPI_AOT_CA_PMT is too short!");
4920 break;
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);
4927 break;
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);
4935 break;
4937 int32_t i;
4939 if(data_len < 4)
4941 cs_log("Error: packet DVBAPI_AOT_CA_STOP is too short!");
4942 break;
4945 // ipbox fix
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);
4962 break;
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)
4973 execlose = 0;
4974 break;
4977 if(execlose)
4979 int32_t ret = close(connfd);
4980 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4984 else
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)); }
4992 break;
4994 default:
4996 cs_log_dbg(D_DVBAPI, "dvbapi_handlesockmsg(): DVBAPI_AOT_CA opcode unknown: %08X", opcode);
4997 break;
5001 if(cfg.dvbapi_listenport && opcode == DVBAPI_AOT_CA_STOP)
5003 (*add_to_poll) = 1;
5005 else
5007 (*add_to_poll) = 0;
5010 else switch(opcode)
5012 case DVBAPI_FILTER_DATA:
5014 if(data_len < 1)
5016 cs_log("Error: packet DVBAPI_FILTER_DATA is too short!");
5017 break;
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);
5026 break;
5029 if(filter_num < 0 || filter_num >= MAX_FILTER)
5031 cs_log("dvbapi_handlesockmsg(): error - received invalid filter_num (%d)", filter_num);
5032 break;
5035 dvbapi_process_input(demux_id, filter_num, mbuf + 6, data_len + 3, msgid);
5036 break;
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);
5056 break;
5058 default:
5060 cs_log_dbg(D_DVBAPI, "dvbapi_handlesockmsg(): opcode unknown: %08X", opcode);
5061 cs_log_dump(mbuf, chunksize, "Unknown command:");
5062 break;
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);
5082 if(recv_result < 1)
5084 (*new_unhandled_len) = unhandled_len;
5085 return (recv_result != -1);
5087 else
5089 unhandled_len += recv_result;
5091 if(unhandled_len < dvbapi_get_nbof_missing_header_bytes(mbuf, unhandled_len))
5093 (*new_unhandled_len) = unhandled_len;
5094 return true;
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;
5108 return true;
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);
5116 if(recv_result < 1)
5118 (*new_unhandled_len) = unhandled_len;
5119 return (recv_result != -1);
5121 else
5123 unhandled_len += recv_result;
5125 if(unhandled_len < chunksize)
5127 (*new_unhandled_len) = unhandled_len;
5128 return true;
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);
5143 packet_count++;
5145 } while(dvbapi_get_nbof_missing_header_bytes(mbuf, unhandled_len) == 0 && packet_count < 7);
5147 (*new_unhandled_len) = unhandled_len;
5148 return true;
5151 static void *dvbapi_main_local(void *cli)
5153 int32_t i, j, l;
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;
5172 ssize_t len = 0;
5173 static const uint16_t mbuf_size = 2048;
5174 uchar *mbuf;
5175 uint16_t unhandled_buf_len[maxpfdsize], unhandled_buf_used[maxpfdsize];
5176 uchar *unhandled_buf[maxpfdsize];
5177 struct s_auth *account;
5178 int32_t ok = 0;
5179 uint16_t client_proto_version[maxpfdsize];
5181 if(!cs_malloc(&mbuf, sizeof(uchar)*mbuf_size))
5183 return NULL;
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)))
5198 { break; }
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.");
5227 free(mbuf);
5228 return NULL;
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();
5239 else
5240 listenfd = dvbapi_net_init_listenfd();
5241 if(listenfd < 1)
5243 cs_log("ERROR: Could not init socket: (errno=%d: %s)", errno, strerror(errno));
5244 free(mbuf);
5245 return NULL;
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);
5264 if(dir_fd >= 0)
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);
5271 else
5273 int32_t ret = start_thread("dvbapi event", dvbapi_event_thread, (void *) dvbapi_client, NULL, 1, 0);
5274 if(ret)
5276 free(mbuf);
5277 return NULL;
5281 if(listenfd != -1)
5283 pfd2[0].fd = listenfd;
5284 pfd2[0].events = (POLLIN | POLLPRI);
5285 type[0] = 1;
5288 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
5289 system("pzapit -rz");
5290 #endif
5291 cs_ftime(&start); // register start time
5292 while(!exit_oscam)
5294 if(pausecam) // for dbox2, STAPI or PC in standby mode dont parse any ecm/emm or try to start next filter
5295 { continue; }
5297 if(cfg.dvbapi_pmtmode == 6)
5299 if(listenfd < 0)
5301 cs_log("PMT6: Trying connect to enigma CA PMT listen socket...");
5302 /* socket init */
5303 if((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
5306 cs_log("socket error (errno=%d %s)", errno, strerror(errno));
5307 listenfd = -1;
5309 else if(connect(listenfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
5311 cs_log("socket connect error (errno=%d %s)", errno, strerror(errno));
5312 close(listenfd);
5313 listenfd = -1;
5315 else
5317 pfd2[0].fd = listenfd;
5318 pfd2[0].events = (POLLIN | POLLPRI);
5319 type[0] = 1;
5320 cs_log("PMT6 CA PMT Server connected on fd %d!", listenfd);
5323 if(listenfd == -1) // not connected!
5325 cs_sleepms(1000);
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);
5353 ids[pfdcount] = i;
5354 fdn[pfdcount] = g;
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!
5370 struct timeb now;
5371 cs_ftime(&now);
5372 int64_t gone;
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);
5380 if(gone > 20*1000){
5382 if(do_emm_start) {
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
5388 if(gone > 5*1000){
5389 if(do_sdt_start)
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
5405 else
5407 gone = comp_timeb(&now, &demux[i].emmstart);
5408 if(gone > 30*1000)
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
5427 started = 1;
5428 break;
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
5446 started = 1;
5447 break;
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);
5485 else
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)
5499 rc = 0;
5500 for(j = 0; j < pfdcount; j++)
5502 if(pfd2[j].fd == demux[i].socket_fd)
5504 rc = 1;
5505 break;
5508 if(rc == 1) { continue; }
5510 pfd2[pfdcount].fd = demux[i].socket_fd;
5511 pfd2[pfdcount].events = (POLLIN | POLLPRI);
5512 ids[pfdcount] = i;
5513 type[pfdcount++] = 1;
5517 rc = 0;
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
5525 continue;
5527 cs_log("ERROR: error on poll of %d fd's (errno=%d %s)", pfdcount, errno, strerror(errno));
5528 break;
5530 else
5532 break;
5536 if(rc > 0)
5538 cs_ftime(&end); // register end time
5539 int64_t timeout = comp_timeb(&end, &start);
5540 if (timeout < 0) {
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))
5555 if(type[i] == 1)
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)
5567 unassoc_fd[j] = 0;
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)
5574 listenfd = -1;
5577 cs_log_dbg(D_DVBAPI, "Socket %d reported hard connection close", pfd2[i].fd);
5579 else // type = 0
5581 int32_t demux_index = ids[i];
5582 int32_t n = fdn[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.
5588 else
5590 int32_t ret, pid;
5591 uchar filter[32];
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);
5599 if(ret != -1)
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));
5608 filter[0] = 0x80;
5609 filter[16] = 0xF0;
5611 sFP.pid = demux[demux_index].ECMpids[pid].ECM_PID;
5612 sFP.timeout = 3000;
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);
5619 if(ret == -1)
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))
5628 if(type[i] == 1)
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) {
5636 connfd = listenfd;
5637 disable_pmt_files = 1;
5638 } else {
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)
5644 //update webif data
5645 client->ip = SIN_GET_ADDR(servaddr);
5646 client->port = ntohs(SIN_GET_PORT(servaddr));
5648 add_to_poll = 1;
5650 if(cfg.dvbapi_pmtmode == 3 || cfg.dvbapi_pmtmode == 0) { disable_pmt_files = 1; }
5652 if(connfd <= 0)
5653 cs_log_dbg(D_DVBAPI, "accept() returns error on fd event %d (errno=%d %s)", pfd2[i].revents, errno, strerror(errno));
5656 else
5658 connfd = pfd2[i].fd;
5661 //reading and completing data from socket
5662 if (connfd > 0) {
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
5676 add_to_poll = 0;
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)
5686 active_conn++;
5689 // remove from unassoc_fd when necessary
5690 if (unassoc_fd[j] == connfd)
5692 unassoc_fd[j] = 0;
5696 close(connfd);
5697 connfd = -1;
5699 if (!active_conn && (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)) //last connection closed
5701 if (cfg.dvbapi_listenport)
5703 //update webif data
5704 client->ip = get_null_ip();
5705 client->port = 0;
5709 continue;
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;
5724 continue;
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
5734 if (add_to_poll) {
5735 for (j = 0; j < MAX_DEMUX; j++) {
5736 if (!unassoc_fd[j]) {
5737 unassoc_fd[j] = connfd;
5738 break;
5744 else // type==0
5746 int32_t demux_index = ids[i];
5747 int32_t n = fdn[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!
5756 continue;
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]);
5774 free(mbuf);
5775 return NULL;
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)
5780 int32_t n;
5781 int8_t cwEmpty = 0;
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++)
5797 char lastcw[9 * 3];
5798 char newcw[9 * 3];
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);
5817 #else
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++)
5829 write_cw = 0;
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)
5835 if(idx != usedidx)
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!
5840 else
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"));
5846 continue;
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"));
5850 write_cw = 1;
5854 if(!write_cw) { continue; } // no need to write the cw since this ca isnt using it!
5856 lastidx = usedidx;
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);
5872 else
5874 if(ca_fd[i] <= 0)
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);
5888 else
5890 if(ca_fd[i] <= 0)
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));
5903 #endif
5908 void delayer(ECM_REQUEST *er, uint32_t delay)
5910 if(delay <= 0) { return; }
5912 struct timeb tpe;
5913 cs_ftime(&tpe);
5914 int64_t gone = comp_timeb(&tpe, &er->tps);
5915 if( gone < delay)
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
5933 #ifdef WITH_STAPI5
5934 if(strcmp(dev_list[demux[i].dev_index].name, er->dev_name) != 0) { continue; } // skip request if PTI device doesn't match request
5935 #endif
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)
5944 { break; }
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;
5954 char ecmd5[17 * 3];
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);
5960 continue;
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);
5965 continue;
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);
5970 nocw_write = 1;
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
5980 comparecw0 = 1;
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
5984 comparecw1 = 1;
5986 if(comparecw0 == 1 || comparecw1 == 1)
5988 cs_log_dbg(D_DVBAPI, "Demuxer %d duplicate controlword ecm response hash %s (duplicate controlword!)", i, ecmd5);
5989 nocw_write = 1;
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);
6072 return;
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);
6083 continue;
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);
6095 continue;
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);
6106 continue;
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);
6124 continue;
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
6145 found = 0;
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
6153 found = 1;
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
6165 found = 1;
6171 continue;
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');
6188 uint32_t delay = 0;
6190 if(delayentry)
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);
6204 delayer(er, delay);
6206 switch(selected_api)
6208 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
6209 case STAPI:
6210 stapi_write_cw(i, er->cw, demux[i].STREAMpids, demux[i].STREAMpidcount, demux[i].pmt_file);
6211 break;
6212 #endif
6213 default:
6215 #ifdef WITH_EXTENDED_CW
6217 if(er->cw_ex.mode != demux[i].ECMpids[j].useMultipleIndices)
6219 ca_index_t idx;
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];
6243 // Video
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)
6248 cw = er->cw;
6250 // Audio
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];
6257 if(key_pos_a < 3)
6259 key_pos_a++;
6262 // Data
6263 else
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);
6271 else
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);
6276 #else
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);
6279 #endif
6280 break;
6284 // reset idle-Time
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); }
6289 #ifndef __CYGWIN__
6290 else if (!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX)
6291 #endif
6292 if(cfg.dvbapi_boxtype != BOXTYPE_SAMYGO)
6293 { dvbapi_write_ecminfo_file(client, er, demux[i].lastcw[0], demux[i].lastcw[1]); }
6296 if(handled == 0)
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)
6306 uint8_t i;
6307 for(i = 0; i < 16; i += 4)
6309 if(((cw[i] + cw[i + 1] + cw[i + 2]) & 0xff) != cw[i + 3])
6311 return 0;
6314 return 1;
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)
6329 char tmp[25];
6330 const char *reader_name = NULL, *from_name = NULL, *proto_name = NULL;
6331 int8_t hops = 0;
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);
6352 else
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);
6372 else
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);
6382 switch(er->rc)
6384 case E_FOUND:
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; }
6390 else
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;
6396 else
6398 reader_name = "none";
6399 from_name = "local";
6400 proto_name = "none";
6402 break;
6404 case E_CACHE1:
6405 reader_name = "Cache";
6406 from_name = "cache1";
6407 proto_name = "none";
6408 break;
6410 case E_CACHE2:
6411 reader_name = "Cache";
6412 from_name = "cache2";
6413 proto_name = "none";
6414 break;
6416 case E_CACHEEX:
6417 reader_name = "Cache";
6418 from_name = "cache3";
6419 proto_name = "none";
6420 break;
6424 if(cfg.dvbapi_ecminfo_type <= ECMINFO_TYPE_OSCAM_MS)
6426 switch(er->rc)
6428 case E_FOUND:
6429 if(er->selected_reader)
6431 fprintf(ecmtxt, "reader: %s\nfrom: %s\nprotocol: %s\nhops: %d\n", reader_name, from_name, proto_name, hops);
6433 break;
6435 case E_CACHE1:
6436 case E_CACHE2:
6437 case E_CACHEEX:
6438 fprintf(ecmtxt, "reader: %s\nfrom: %s\nprotocol: %s\n", reader_name, from_name, proto_name);
6439 break;
6442 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_OSCAM)
6443 { fprintf(ecmtxt, "ecm time: %.3f\n", (float) client->cwlastresptime / 1000); }
6444 else
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)));
6454 else
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)
6462 time_t walltime;
6463 struct tm lt;
6464 char timebuf[32];
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, &lt);
6476 if(strftime(timebuf, 32, "%a %b %d %H:%M:%S %Y", &lt) != 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);
6493 if(ecmtxt)
6495 int32_t ret = fclose(ecmtxt);
6496 if(ret < 0) { cs_log("ERROR: Could not close ecmtxt fd (errno=%d %s)", errno, strerror(errno)); }
6497 ecmtxt = NULL;
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;
6509 cl->typ = 'c';
6510 int32_t ret = start_thread("dvbapi handler", _main_func, (void *) cl, &cl->thread, 1, 0);
6511 if(ret)
6513 return NULL;
6517 return NULL;
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; }
6529 if(USE_OPENXCAS)
6531 return 0;
6534 if(selected_api != DVBAPI_3 && selected_api != DVBAPI_1 && selected_api != STAPI) // only valid for dvbapi3, dvbapi1 and STAPI
6536 return 0;
6539 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX || cfg.dvbapi_boxtype == BOXTYPE_IPBOX_PMT) // reported buggy using sectionfiltering after 1~4 hours -> for now disabled!
6541 return 0;
6544 if(n == -1)
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
6554 uchar filter[16];
6555 uchar mask[16];
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;
6561 if(pid != -1)
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)
6574 mask[0] = 0xFF;
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
6581 mask[0] = 0xF0;
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)
6595 case 0x01:
6596 offset = 7;
6597 extramask = 0xF0;
6598 break; // seca
6599 case 0x05:
6600 offset = 8;
6601 break; // viaccess
6602 case 0x06:
6603 offset = 6;
6604 break; // irdeto
6605 case 0x09:
6606 offset = 11;
6607 break; // videoguard
6608 case 0x4A: // DRE-Crypt, Bulcrypt,Tongang and others?
6609 if(!caid_is_bulcrypt(er->caid))
6610 { offset = 6; }
6611 break;
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);
6629 else
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;
6634 mask[2] = 0xFF;
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);
6648 if(ret == -1)
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);
6654 return -1;
6656 return n;
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)
6662 int32_t ret = -1;
6664 switch(selected_api)
6666 case DVBAPI_3:
6668 struct dmx_sct_filter_params sFP2;
6669 memset(&sFP2, 0, sizeof(sFP2));
6670 sFP2.pid = pid;
6671 sFP2.timeout = 0;
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);
6695 else
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);
6701 else
6702 ret = dvbapi_ioctl(fd, DMX_SET_FILTER, &sFP2);
6704 break;
6707 case DVBAPI_1:
6709 struct dmxSctFilterParams sFP1;
6710 memset(&sFP1, 0, sizeof(sFP1));
6711 sFP1.pid = pid;
6712 sFP1.timeout = 0;
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);
6717 break;
6719 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
6720 case STAPI:
6722 ret = stapi_activate_section_filter(fd, filter, mask);
6723 break;
6725 #endif
6726 // Isn't implemented in COOLAPI-1 (legacy)
6727 #if defined WITH_COOLAPI2
6728 case COOLAPI:
6730 int32_t n = coolapi_get_filter_num(fd);
6731 if (n < 0)
6732 return n;
6733 coolapi_set_filter(fd, n, pid, filter, mask, TYPE_ECM);
6734 break;
6736 #endif
6738 default:
6739 break;
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
6746 return ret;
6750 int32_t dvbapi_check_ecm_delayed_delivery(int32_t demux_index, ECM_REQUEST *er)
6752 int32_t ret = 0;
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
6761 char ecmd5[17 * 3];
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;
6775 if(pid !=-1)
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
6784 return ret;
6787 int32_t dvbapi_get_filternum(int32_t demux_index, ECM_REQUEST *er, int32_t type)
6789 if(!er) { return -1; }
6791 int32_t n;
6792 int32_t fd = -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!
6808 break;
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)
6819 ca_index_t idx;
6820 int32_t n;
6822 if(pid == -1 || pid > demux[demux_index].ECMpidcount) return INDEX_INVALID;
6824 if(demux[demux_index].ECMpids[pid].useMultipleIndices)
6826 n = stream_id;
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
6847 else
6849 dvbapi_set_pid(demux_index, n, idx, false, false, msgid); // disable streampid
6852 else
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
6876 else
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;
6889 LL_ITER itr;
6891 if(!ll_activestreampids)
6892 { ll_activestreampids = ll_create("ll_activestreampids"); }
6894 if(idx > INDEX_MAX)
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
6912 }else{
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;
6942 int8_t removed = 0;
6943 LL_ITER itr;
6945 if(!ll_activestreampids)
6946 { return NO_STREAMPID_LISTED; }
6948 if(idx > INDEX_MAX)
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;
6960 removed = 1;
6962 else if((listitem->activeindexers & (1 << idx)) == (uint64_t) (1 << idx))
6964 listitem->activeindexers &= ~(1 << idx); // flag it as disabled for this index
6965 removed = 1;
6968 if(removed)
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;
6984 else
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!
7008 int32_t j;
7010 if(demux[demux_id].ECMpids[ecmpid].useMultipleIndices == 0)
7012 ca_index_t idx = demux[demux_id].ECMpids[ecmpid].index[0];
7013 int32_t i,n;
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
7020 LL_ITER itr;
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;
7030 break;
7032 if (listitem->streampid == demux[demux_id].STREAMpids[n]){ // check if pid matches with current streampid on demuxer
7033 break;
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
7054 break;
7057 if(!listitem) // if streampid not listed -> enable it!
7059 dvbapi_set_pid(demux_id, n, idx, true, false, 0); // enable streampid
7065 else
7067 ca_index_t idx = INDEX_INVALID;
7068 int32_t i,n;
7069 uint8_t skip;
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
7076 LL_ITER itr;
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
7090 break;
7094 if(skip) continue;
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;
7100 break;
7102 if (listitem->streampid == demux[demux_id].STREAMpids[n]){ // check if pid matches with current streampid on demuxer
7103 break;
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
7130 break;
7134 if(skip) continue;
7136 if (listitem->streampid == demux[demux_id].STREAMpids[n]) // check if pid matches with current streampid on demuxer
7138 break;
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;
7155 LL_ITER itr;
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)
7166 { continue; }
7168 if(pid && listitem->streampid != pid)
7169 { continue; }
7171 uint32_t i = 0;
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);
7178 break;
7180 i++;
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)
7207 if (l<0) return;
7209 uint32_t typtext_idx = 0;
7210 int32_t ret = -1;
7211 const char *typtext[] = { "UNIQUE", "SHARED", "GLOBAL", "UNKNOWN" };
7213 while(((emmtype >> typtext_idx) & 0x01) == 0 && typtext_idx < sizeof(typtext) / sizeof(const char *))
7215 ++typtext_idx;
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);
7223 return;
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);
7241 return;
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);
7248 return;
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;
7272 struct timeb now;
7273 cs_ftime(&now);
7275 struct s_emm_filter *filter_item;
7276 LL_ITER itr;
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)
7282 { break; }
7283 int64_t gone = comp_timeb(&now, &filter_item->time_started);
7284 if( gone > 45*1000)
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);
7296 stopped++;
7300 int32_t ret;
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);
7311 if(ret != -1)
7313 ll_iter_remove_data(&itr2);
7314 started++;
7315 break;
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;
7334 uint8_t flt, mask;
7335 match = 1;
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
7341 k += 2;
7343 if(!mask)
7345 continue;
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);
7350 if(k <= len)
7352 match = (flt == (buffer[k] & mask));
7354 else
7356 match = 0;
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
7378 #else
7379 ph->s_handler = dvbapi_handler;
7380 ph->send_dcw = dvbapi_send_dcw;
7381 #endif
7383 #endif // HAVE_DVBAPI