DVBAPI:
[oscam.git] / module-dvbapi.c
blob42b841753085a3370ee626a2b394be86c69786f6
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, 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;
490 // not connected?
491 if (socket_fd <= 0)
492 return 0;
494 // preparing packet - header
495 // in old protocol client expect this first byte as adapter index, changed in the new protocol
496 // to be always after request type (opcode)
497 if (client_proto_version <= 0)
498 packet[size++] = demux[demux_index].adapter_index; //adapter index - 1 byte
500 // type of request
501 uint32_t req = request;
502 if (client_proto_version >= 1)
503 req = htonl(req);
504 memcpy(&packet[size], &req, 4); //request - 4 bytes
505 size += 4;
507 // preparing packet - adapter index for proto >= 1
508 if ((request != DVBAPI_SERVER_INFO) && client_proto_version >= 1)
509 packet[size++] = demux[demux_index].adapter_index; //adapter index - 1 byte
511 // struct with data
512 switch (request)
514 case DVBAPI_SERVER_INFO:
516 int16_t proto_version = htons(DVBAPI_PROTOCOL_VERSION); //our protocol version
517 memcpy(&packet[size], &proto_version, 2);
518 size += 2;
520 unsigned char *info_len = &packet[size]; //info string length
521 size += 1;
523 *info_len = snprintf((char *) &packet[size], sizeof(packet) - size, "OSCam v%s, build r%s (%s)", CS_VERSION, CS_SVN_VERSION, CS_TARGET);
524 size += *info_len;
525 break;
527 case DVBAPI_ECM_INFO:
529 if (er->rc >= E_NOTFOUND)
530 return 0;
532 int8_t hops = 0;
534 uint16_t sid = htons(er->srvid); //service ID (program number)
535 memcpy(&packet[size], &sid, 2);
536 size += 2;
538 uint16_t caid = htons(er->caid); //CAID
539 memcpy(&packet[size], &caid, 2);
540 size += 2;
542 uint16_t pid = htons(er->pid); //PID
543 memcpy(&packet[size], &pid, 2);
544 size += 2;
546 uint32_t prid = htonl(er->prid); //Provider ID
547 memcpy(&packet[size], &prid, 4);
548 size += 4;
550 uint32_t ecmtime = htonl(client->cwlastresptime); //ECM time
551 memcpy(&packet[size], &ecmtime, 4);
552 size += 4;
554 dvbapi_net_add_str(packet, &size, get_cardsystem_desc_by_caid(er->caid)); //cardsystem name
556 switch (er->rc)
558 case E_FOUND:
559 if (er->selected_reader)
561 dvbapi_net_add_str(packet, &size, er->selected_reader->label); //reader
562 if (is_network_reader(er->selected_reader))
563 dvbapi_net_add_str(packet, &size, er->selected_reader->device); //from
564 else
565 dvbapi_net_add_str(packet, &size, "local"); //from
566 dvbapi_net_add_str(packet, &size, reader_get_type_desc(er->selected_reader, 1)); //protocol
567 hops = er->selected_reader->currenthops;
569 break;
571 case E_CACHE1:
572 dvbapi_net_add_str(packet, &size, "Cache"); //reader
573 dvbapi_net_add_str(packet, &size, "cache1"); //from
574 dvbapi_net_add_str(packet, &size, "none"); //protocol
575 break;
577 case E_CACHE2:
578 dvbapi_net_add_str(packet, &size, "Cache"); //reader
579 dvbapi_net_add_str(packet, &size, "cache2"); //from
580 dvbapi_net_add_str(packet, &size, "none"); //protocol
581 break;
583 case E_CACHEEX:
584 dvbapi_net_add_str(packet, &size, "Cache"); //reader
585 dvbapi_net_add_str(packet, &size, "cache3"); //from
586 dvbapi_net_add_str(packet, &size, "none"); //protocol
587 break;
590 packet[size++] = hops; //hops
592 break;
594 case DVBAPI_CA_SET_PID:
596 int sct_capid_size = sizeof(ca_pid_t);
598 if (client_proto_version >= 1)
600 ca_pid_t *capid = (ca_pid_t *) data;
601 capid->pid = htonl(capid->pid);
602 capid->index = htonl(capid->index);
604 memcpy(&packet[size], data, sct_capid_size);
606 size += sct_capid_size;
607 break;
609 case DVBAPI_CA_SET_DESCR:
611 int sct_cadescr_size = sizeof(ca_descr_t);
613 if (client_proto_version >= 1)
615 ca_descr_t *cadesc = (ca_descr_t *) data;
616 cadesc->index = htonl(cadesc->index);
617 cadesc->parity = htonl(cadesc->parity);
619 memcpy(&packet[size], data, sct_cadescr_size);
621 size += sct_cadescr_size;
622 break;
624 case DVBAPI_CA_SET_DESCR_MODE:
626 int sct_cadescr_mode_size = sizeof(ca_descr_mode_t);
628 if (client_proto_version >= 1)
630 ca_descr_mode_t *cadesc_mode = (ca_descr_mode_t *) data;
631 cadesc_mode->index = htonl(cadesc_mode->index);
632 cadesc_mode->algo = htonl(cadesc_mode->algo);
633 cadesc_mode->cipher_mode = htonl(cadesc_mode->cipher_mode);
635 memcpy(&packet[size], data, sct_cadescr_mode_size);
637 size += sct_cadescr_mode_size;
638 break;
640 case DVBAPI_DMX_SET_FILTER:
641 case DVBAPI_DMX_STOP:
643 int32_t sct_filter_size = sizeof(struct dmx_sct_filter_params);
644 packet[size++] = demux_index; //demux index - 1 byte
645 packet[size++] = filter_number; //filter number - 1 byte
647 if (data) // filter data when starting
649 if (client_proto_version >= 1)
651 struct dmx_sct_filter_params *fp = (struct dmx_sct_filter_params *) data;
653 // adding all dmx_sct_filter_params structure fields
654 // one by one to avoid padding problems
655 uint16_t pid = htons(fp->pid);
656 memcpy(&packet[size], &pid, 2);
657 size += 2;
659 memcpy(&packet[size], fp->filter.filter, 16);
660 size += 16;
661 memcpy(&packet[size], fp->filter.mask, 16);
662 size += 16;
663 memcpy(&packet[size], fp->filter.mode, 16);
664 size += 16;
666 uint32_t timeout = htonl(fp->timeout);
667 memcpy(&packet[size], &timeout, 4);
668 size += 4;
670 uint32_t flags = htonl(fp->flags);
671 memcpy(&packet[size], &flags, 4);
672 size += 4;
674 else
676 memcpy(&packet[size], data, sct_filter_size); //dmx_sct_filter_params struct
677 size += sct_filter_size;
680 else // pid when stopping
682 if (client_proto_version >= 1)
684 uint16_t pid = htons(demux[demux_index].demux_fd[filter_number].pid);
685 memcpy(&packet[size], &pid, 2);
686 size += 2;
688 else
690 uint16_t pid = demux[demux_index].demux_fd[filter_number].pid;
691 packet[size++] = pid >> 8;
692 packet[size++] = pid & 0xff;
695 break;
697 default: //unknown request
699 cs_log("ERROR: dvbapi_net_send: invalid request");
700 return 0;
704 // sending
705 cs_log_dump_dbg(D_DVBAPI, packet, size, "Sending packet to dvbapi client (fd=%d):", socket_fd);
706 send(socket_fd, &packet, size, MSG_DONTWAIT);
708 // always returning success as the client could close socket
709 return 0;
712 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,
713 int8_t add_to_emm_list)
715 int32_t ret = -1, n = -1, i, filterfd = -1;
717 for(i = 0; i < maxfilter && demux[demux_id].demux_fd[i].fd > 0; i++) { ; }
719 if(i >= maxfilter)
721 cs_log_dbg(D_DVBAPI, "no free filter");
722 return -1;
724 n = i;
726 if(USE_OPENXCAS)
728 if(type == TYPE_ECM)
730 openxcas_set_caid(demux[demux_id].ECMpids[pidindex].CAID);
731 openxcas_set_ecm_pid(pid);
733 demux[demux_id].demux_fd[n].fd = DUMMY_FD;
734 demux[demux_id].demux_fd[n].pidindex = pidindex;
735 demux[demux_id].demux_fd[n].pid = pid;
736 demux[demux_id].demux_fd[n].caid = caid;
737 demux[demux_id].demux_fd[n].provid = provid;
738 demux[demux_id].demux_fd[n].type = type;
739 memcpy(demux[demux_id].demux_fd[n].filter, filt, 16); // copy filter to check later on if receiver delivered accordingly
740 memcpy(demux[demux_id].demux_fd[n].mask, mask, 16); // copy mask to check later on if receiver delivered accordingly
741 return 1;
744 switch(api)
746 case DVBAPI_3:
747 if (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
748 ret = filterfd = DUMMY_FD;
749 else
750 ret = filterfd = dvbapi_open_device(0, demux[demux_id].demux_index, demux[demux_id].adapter_index);
751 if(ret < 0) { return ret; } // return if device cant be opened!
752 struct dmx_sct_filter_params sFP2;
754 memset(&sFP2, 0, sizeof(sFP2));
756 sFP2.pid = pid;
757 sFP2.timeout = timeout;
758 sFP2.flags = DMX_IMMEDIATE_START;
759 if(cfg.dvbapi_boxtype == BOXTYPE_NEUMO)
761 //DeepThought: on dgs/cubestation and neumo images, perhaps others
762 //the following code is needed to descramble
763 sFP2.filter.filter[0] = filt[0];
764 sFP2.filter.mask[0] = mask[0];
765 sFP2.filter.filter[1] = 0;
766 sFP2.filter.mask[1] = 0;
767 sFP2.filter.filter[2] = 0;
768 sFP2.filter.mask[2] = 0;
769 memcpy(sFP2.filter.filter + 3, filt + 1, 16 - 3);
770 memcpy(sFP2.filter.mask + 3, mask + 1, 16 - 3);
771 //DeepThought: in the drivers of the dgs/cubestation and neumo images,
772 //dvbapi 1 and 3 are somehow mixed. In the kernel drivers, the DMX_SET_FILTER
773 //ioctl expects to receive a dmx_sct_filter_params structure (DVBAPI 3) but
774 //due to a bug its sets the "positive mask" wrongly (they should be all 0).
775 //On the other hand, the DMX_SET_FILTER1 ioctl also uses the dmx_sct_filter_params
776 //structure, which is incorrect (it should be dmxSctFilterParams).
777 //The only way to get it right is to call DMX_SET_FILTER1 with the argument
778 //expected by DMX_SET_FILTER. Otherwise, the timeout parameter is not passed correctly.
779 ret = dvbapi_ioctl(filterfd, DMX_SET_FILTER1, &sFP2);
781 else
783 memcpy(sFP2.filter.filter, filt, 16);
784 memcpy(sFP2.filter.mask, mask, 16);
785 if (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
786 ret = dvbapi_net_send(DVBAPI_DMX_SET_FILTER, demux[demux_id].socket_fd, demux_id, n, (unsigned char *) &sFP2, NULL, NULL, demux[demux_id].client_proto_version);
787 else
788 ret = dvbapi_ioctl(filterfd, DMX_SET_FILTER, &sFP2);
790 break;
792 case DVBAPI_1:
793 ret = filterfd = dvbapi_open_device(0, demux[demux_id].demux_index, demux[demux_id].adapter_index);
794 if(ret < 0) { return ret; } // return if device cant be opened!
795 struct dmxSctFilterParams sFP1;
797 memset(&sFP1, 0, sizeof(sFP1));
799 sFP1.pid = pid;
800 sFP1.timeout = timeout;
801 sFP1.flags = DMX_IMMEDIATE_START;
802 memcpy(sFP1.filter.filter, filt, 16);
803 memcpy(sFP1.filter.mask, mask, 16);
804 ret = dvbapi_ioctl(filterfd, DMX_SET_FILTER1, &sFP1);
806 break;
807 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
808 case STAPI:
809 ret = filterfd = stapi_set_filter(demux_id, pid, filt, mask, n, demux[demux_id].pmt_file);
810 if(ret <= 0)
812 ret = -1; // error setting filter!
814 break;
815 #endif
816 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
817 case COOLAPI:
818 ret = filterfd = coolapi_open_device(demux[demux_id].demux_index, demux_id);
819 if(ret > 0)
821 ret = coolapi_set_filter(filterfd, n, pid, filt, mask, type);
823 else
825 ret = -1; // fail
827 break;
828 #endif
829 default:
830 break;
832 if(ret != -1) // filter set successful
834 // only register if filter was set successful
835 demux[demux_id].demux_fd[n].fd = filterfd;
836 demux[demux_id].demux_fd[n].pidindex = pidindex;
837 demux[demux_id].demux_fd[n].pid = pid;
838 demux[demux_id].demux_fd[n].caid = caid;
839 demux[demux_id].demux_fd[n].provid = provid;
840 demux[demux_id].demux_fd[n].type = type;
841 memcpy(demux[demux_id].demux_fd[n].filter, filt, 16); // copy filter to check later on if receiver delivered accordingly
842 memcpy(demux[demux_id].demux_fd[n].mask, mask, 16); // copy mask to check later on if receiver delivered accordingly
843 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d started successfully (caid %04X provid %06X pid %04X)", demux_id, n + 1, caid, provid, pid);
844 if(type == TYPE_EMM && add_to_emm_list){
845 add_emmfilter_to_list(demux_id, filt, caid, provid, pid, n + 1, true);
848 else
850 cs_log("ERROR: Could not start demux filter (api: %d errno=%d %s)", selected_api, errno, strerror(errno));
853 return ret;
856 static int32_t dvbapi_detect_api(void)
858 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
859 selected_api = COOLAPI;
860 selected_box = BOX_INDEX_COOLSTREAM;
861 disable_pmt_files = 1;
862 cfg.dvbapi_listenport = 0;
863 cs_log("Detected Coolstream API");
864 return 1;
865 #else
866 if (cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX || cfg.dvbapi_boxtype == BOXTYPE_PC ) {
867 selected_api = DVBAPI_3;
868 selected_box = BOX_INDEX_DREAMBOX_DVBAPI3;
869 if (cfg.dvbapi_listenport)
871 cs_log("Using TCP listen socket, API forced to DVBAPIv3 (%d), userconfig boxtype: %d", selected_api, cfg.dvbapi_boxtype);
873 else
875 cs_log("Using %s listen socket, API forced to DVBAPIv3 (%d), userconfig boxtype: %d", devices[selected_box].cam_socket_path, selected_api, cfg.dvbapi_boxtype);
877 return 1;
879 else if(cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
881 selected_api = DVBAPI_3;
882 selected_box = BOX_INDEX_QBOXHD;
883 cfg.dvbapi_listenport = 0;
884 disable_pmt_files = 1;
885 cs_log("Using SamyGO dvbapi v0.1");
886 return 1;
888 else
890 cfg.dvbapi_listenport = 0;
893 int32_t i = 0, n = 0, devnum = -1, dmx_fd = 0, filtercount = 0;
894 char device_path[128], device_path2[128];
895 static LLIST *ll_max_fd;
896 ll_max_fd = ll_create("ll_max_fd");
897 LL_ITER itr;
899 struct s_open_fd
901 uint32_t fd;
904 struct s_open_fd *open_fd;
906 while (i < BOX_COUNT)
910 snprintf(device_path2, sizeof(device_path2), devices[i].demux_device, 0);
911 snprintf(device_path, sizeof(device_path), devices[i].path, n);
912 strncat(device_path, device_path2, sizeof(device_path) - strlen(device_path) - 1);
913 filtercount = 0;
914 while((dmx_fd = open(device_path, O_RDWR | O_NONBLOCK)) > 0 && filtercount < MAX_FILTER)
916 filtercount++;
917 if(!cs_malloc(&open_fd, sizeof(struct s_open_fd)))
919 close(dmx_fd);
920 break;
922 open_fd->fd = dmx_fd;
923 ll_append(ll_max_fd, open_fd);
926 if(filtercount > 0)
928 itr = ll_iter_create(ll_max_fd);
929 while((open_fd = ll_iter_next(&itr)))
931 dmx_fd = open_fd->fd;
936 while(close(dmx_fd)<0);
937 ll_iter_remove_data(&itr);
939 devnum = i;
940 selected_api = devices[devnum].api;
941 selected_box = devnum;
942 if(cfg.dvbapi_boxtype == BOXTYPE_NEUMO)
944 selected_api = DVBAPI_3; //DeepThought
946 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
947 if(selected_api == STAPI && stapi_open() == 0)
949 cs_log("ERROR: stapi: setting up stapi failed.");
950 return 0;
952 #endif
953 maxfilter = filtercount;
954 cs_log("Detected %s Api: %d, userconfig boxtype: %d maximum amount of possible filters is %d (oscam limit is %d)",
955 device_path, selected_api, cfg.dvbapi_boxtype, filtercount, MAX_FILTER);
958 /* try at least 8 adapters */
959 if ((strchr(devices[i].path, '%') != NULL) && (n < 8)) n++; else { n = 0; i++; }
960 }while(n != 0); // n is set to 0 again if 8 adapters are tried!
962 if(devnum != -1) break; // check if box detected
965 ll_destroy(&ll_max_fd);
967 if(devnum == -1) { return 0; }
969 #endif
970 return 1;
973 static int32_t dvbapi_read_device(int32_t dmx_fd, unsigned char *buf, uint32_t length)
975 int32_t readed;
976 uint32_t count = 0;
977 struct pollfd pfd[1];
979 pfd[0].fd = dmx_fd;
980 pfd[0].events = (POLLIN | POLLPRI);
982 while (count < length )
984 if (poll(pfd,1,0)) // fd ready for reading?
986 if (pfd[0].revents & (POLLIN | POLLPRI)) // is there data to read?
988 readed = read(dmx_fd, &buf[count], length-count);
989 if(readed < 0) // error occured while reading
991 if(errno == EINTR || errno == EAGAIN) { continue; } // try again in case of interrupt
992 cs_log("ERROR: Read error on fd %d (errno=%d %s)", dmx_fd, errno, strerror(errno));
993 return (errno == EOVERFLOW ? 0 : -1);
995 if(readed > 0) // succesfull read
997 count += readed;
999 if(readed == 0 && count > 0) // nothing to read left
1001 break;
1004 else return -1; // other events than pollin/pri means bad news -> abort!
1006 else break;
1008 cs_log_dump_dbg(D_TRACE, buf, count, "Received:");
1009 return count;
1012 int32_t dvbapi_open_device(int32_t type, int32_t num, int32_t adapter)
1014 int32_t dmx_fd, ret;
1015 int32_t ca_offset = 0;
1016 char device_path[128], device_path2[128];
1018 if(cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
1019 return DUMMY_FD;
1021 if(type == 0)
1023 snprintf(device_path2, sizeof(device_path2), devices[selected_box].demux_device, num);
1024 snprintf(device_path, sizeof(device_path), devices[selected_box].path, adapter);
1026 strncat(device_path, device_path2, sizeof(device_path) - strlen(device_path) - 1);
1028 else
1030 if(cfg.dvbapi_boxtype == BOXTYPE_DUCKBOX || cfg.dvbapi_boxtype == BOXTYPE_DBOX2 || cfg.dvbapi_boxtype == BOXTYPE_UFS910)
1031 { ca_offset = 1; }
1033 if(cfg.dvbapi_boxtype == BOXTYPE_QBOXHD)
1034 { num = 0; }
1036 if(cfg.dvbapi_boxtype == BOXTYPE_PC)
1037 { num = 0; }
1039 if(cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
1040 { num = 0; }
1042 snprintf(device_path2, sizeof(device_path2), devices[selected_box].ca_device, num + ca_offset);
1043 snprintf(device_path, sizeof(device_path), devices[selected_box].path, adapter);
1045 strncat(device_path, device_path2, sizeof(device_path) - strlen(device_path) - 1);
1048 if (cfg.dvbapi_boxtype == BOXTYPE_SAMYGO) {
1050 if(type == 0)
1052 struct sockaddr_un saddr;
1053 memset(&saddr, 0, sizeof(saddr));
1054 saddr.sun_family = AF_UNIX;
1055 strncpy(saddr.sun_path, device_path, sizeof(saddr.sun_path) - 1);
1056 dmx_fd = socket(AF_UNIX, SOCK_STREAM, 0);
1057 ret = connect(dmx_fd, (struct sockaddr *)&saddr, sizeof(saddr));
1058 if (ret < 0)
1059 { close(dmx_fd); }
1061 else if(type == 1)
1063 int32_t udp_port = 9000;
1064 struct sockaddr_in saddr;
1065 memset(&saddr, 0, sizeof(saddr));
1066 saddr.sin_family = AF_INET;
1067 saddr.sin_port = htons(udp_port + adapter);
1068 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
1069 dmx_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
1070 set_nonblock(dmx_fd, true);
1071 ret = connect(dmx_fd, (struct sockaddr *) &saddr, sizeof(saddr));
1072 if(ret < 0)
1073 { close(dmx_fd); }
1075 cs_log_dbg(D_DVBAPI, "NET DEVICE open (port = %d) fd %d", udp_port + adapter, dmx_fd);
1077 else
1079 ret = -1;
1081 } else {
1082 dmx_fd = ret = open(device_path, O_RDWR | O_NONBLOCK);
1085 if(ret < 0)
1087 cs_log("ERROR: Can't open device %s (errno=%d %s)", device_path, errno, strerror(errno));
1088 return -1;
1091 cs_log_dbg(D_DVBAPI, "Open device %s (fd %d)", device_path, dmx_fd);
1093 return dmx_fd;
1096 uint16_t tunemm_caid_map(uint8_t direct, uint16_t caid, uint16_t srvid)
1098 int32_t i;
1099 struct s_client *cl = cur_client();
1100 TUNTAB *ttab = &cl->ttab;
1102 if (!ttab->ttnum)
1103 return caid;
1105 if(direct)
1107 for(i = 0; i < ttab->ttnum; i++)
1109 if(caid == ttab->ttdata[i].bt_caidto
1110 && (srvid == ttab->ttdata[i].bt_srvid || ttab->ttdata[i].bt_srvid == 0xFFFF || !ttab->ttdata[i].bt_srvid))
1111 { return ttab->ttdata[i].bt_caidfrom; }
1114 else
1116 for(i = 0; i < ttab->ttnum; i++)
1118 if(caid == ttab->ttdata[i].bt_caidfrom
1119 && (srvid == ttab->ttdata[i].bt_srvid || ttab->ttdata[i].bt_srvid == 0xFFFF || !ttab->ttdata[i].bt_srvid))
1120 { return ttab->ttdata[i].bt_caidto; }
1123 return caid;
1126 int32_t dvbapi_stop_filter(int32_t demux_index, int32_t type)
1128 int32_t g, error = 0;
1130 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
1132 if(demux[demux_index].demux_fd[g].type == type)
1134 if(dvbapi_stop_filternum(demux_index, g) == -1)
1136 error = 1;
1140 return !error; // on error return 0, all ok 1
1143 int32_t dvbapi_stop_filternum(int32_t demux_index, int32_t num)
1145 int32_t retfilter = -1, retfd = -1, fd = demux[demux_index].demux_fd[num].fd, try = 0;
1146 if(USE_OPENXCAS)
1148 demux[demux_index].demux_fd[num].type = 0;
1149 demux[demux_index].demux_fd[num].fd = 0;
1150 return 1; // all ok!
1153 if(fd > 0)
1157 if(try)
1159 cs_sleepms(50);
1161 try++;
1162 cs_log_dbg(D_DVBAPI, "Demuxer %d stop filter %d try %d (fd: %d api: %d, caid: %04X, provid: %06X, %spid: %04X)", demux_index, num + 1, try,
1163 fd, selected_api, demux[demux_index].demux_fd[num].caid, demux[demux_index].demux_fd[num].provid,
1164 (demux[demux_index].demux_fd[num].type == TYPE_ECM ? "ecm" : "emm"), demux[demux_index].demux_fd[num].pid);
1166 switch(selected_api)
1168 case DVBAPI_3:
1169 if (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
1170 retfilter = dvbapi_net_send(DVBAPI_DMX_STOP, demux[demux_index].socket_fd, demux_index, num, NULL, NULL, NULL, demux[demux_index].client_proto_version);
1171 else
1172 retfilter = dvbapi_ioctl(fd, DMX_STOP, NULL);
1173 break;
1175 case DVBAPI_1:
1176 retfilter = dvbapi_ioctl(fd, DMX_STOP, NULL);
1177 break;
1179 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
1180 case STAPI:
1181 retfilter = stapi_remove_filter(demux_index, num, demux[demux_index].pmt_file);
1182 if(retfilter != 1) // stapi returns 0 for error, 1 for all ok
1184 retfilter = -1;
1186 break;
1187 #endif
1188 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
1189 case COOLAPI:
1190 retfilter = coolapi_remove_filter(fd, num);
1191 if(retfilter >=0 )
1193 retfd = coolapi_close_device(fd);
1195 break;
1196 #endif
1197 default:
1198 break;
1200 if(errno == 9) {retfilter = 0;} // no error on bad file descriptor
1201 } while (retfilter < 0 && try < 10);
1203 #if !defined WITH_COOLAPI && !defined WITH_COOLAPI2 // no fd close for coolapi and stapi, all others do close fd!
1204 try = 0;
1207 if(try)
1209 cs_sleepms(50);
1211 try++;
1212 if (!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX && errno != 9) //on bad filterfd dont try to close!
1214 if(selected_api == STAPI)
1216 retfd = 0; // stapi closes its own filter fd!
1218 else
1220 flush_read_fd(demux_index, num, fd); // flush filter input buffer in attempt to avoid overflow receivers internal buffer
1221 retfd = close(fd);
1222 if(errno == 9) { retfd = 0; } // no error on bad file descriptor
1225 else
1226 retfd = 0;
1228 } while (retfd < 0 && try < 10);
1229 #endif
1231 else // fd <=0
1233 return 1; // filter was already killed!
1236 if(retfilter < 0) // error on remove filter
1238 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));
1239 return retfilter;
1242 if(retfd < 0) // error on close filter fd
1244 cs_log("ERROR: Demuxer %d could not close fd of Filter %d (fd=%d api:%d errno=%d %s)", demux_index, num + 1, fd,
1245 selected_api, errno, strerror(errno));
1246 return retfd;
1249 // code below runs only if nothing has gone wrong
1251 if(demux[demux_index].demux_fd[num].type == TYPE_ECM) //ecm filter stopped: reset index!
1253 int32_t oldpid = demux[demux_index].demux_fd[num].pidindex;
1254 int32_t curpid = demux[demux_index].pidindex;
1256 // workaround: below dont run on stapi since it handles it own pids.... stapi need to be better integrated in oscam dvbapi.
1257 if(selected_api != STAPI)
1259 int32_t z;
1260 for(z = 0; z < MAX_STREAM_INDICES; z++)
1262 ca_index_t idx = demux[demux_index].ECMpids[oldpid].index[z];
1263 demux[demux_index].ECMpids[oldpid].index[z] = INDEX_INVALID;
1265 if(idx != INDEX_INVALID) // if in use
1267 int32_t i;
1268 for(i = 0; i < demux[demux_index].STREAMpidcount; i++)
1270 int8_t match = 0;
1271 // check streams of old disabled ecmpid
1272 if(!demux[demux_index].ECMpids[oldpid].streams || ((demux[demux_index].ECMpids[oldpid].streams & (1 << i)) == (uint) (1 << i)))
1274 // check if new ecmpid is using same streams
1275 if(curpid != -1 && (!demux[demux_index].ECMpids[curpid].streams || ((demux[demux_index].ECMpids[curpid].streams & (1 << i)) == (uint) (1 << i))))
1277 continue; // found same stream on old and new ecmpid -> skip! (and leave it enabled!)
1280 int32_t pidtobestopped = demux[demux_index].STREAMpids[i];
1281 int32_t j, k, otherdemuxpid;
1282 ca_index_t otherdemuxidx;
1284 for(j = 0; j < MAX_DEMUX; j++) // check other demuxers for same streampid with same index
1286 if(demux[j].program_number == 0) { continue; } // skip empty demuxers
1287 if(demux_index == j) { continue; } // skip same demuxer
1288 if(demux[j].ca_mask != demux[demux_index].ca_mask) { continue;} // skip streampid running on other ca device
1290 otherdemuxpid = demux[j].pidindex;
1291 if(otherdemuxpid == -1) { continue; } // Other demuxer not descrambling yet
1293 int32_t y;
1294 for(y = 0; y < MAX_STREAM_INDICES; y++)
1296 otherdemuxidx = demux[j].ECMpids[otherdemuxpid].index[y];
1297 if(otherdemuxidx == INDEX_INVALID || otherdemuxidx != idx) { continue; } // Other demuxer has no index yet, or index is different
1299 for(k = 0; k < demux[j].STREAMpidcount; k++)
1301 if(!demux[j].ECMpids[otherdemuxpid].streams || ((demux[j].ECMpids[otherdemuxpid].streams & (1 << k)) == (uint) (1 << k)))
1303 if(demux[j].STREAMpids[k] == pidtobestopped)
1305 continue; // found same streampid enabled with same index on one or more other demuxers -> skip! (and leave it enabled!)
1308 match = 1; // matching stream found
1313 if(!match)
1315 remove_streampid_from_list(demux[demux_index].ca_mask, pidtobestopped, idx);
1316 //dvbapi_set_pid(demux_index, i, idx, false, false); // disable streampid since its not used by this pid (or by the new ecmpid or any other demuxer!)
1325 if(demux[demux_index].demux_fd[num].type == TYPE_EMM) // If emm type remove from emm filterlist
1327 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);
1329 demux[demux_index].demux_fd[num].type = 0;
1330 demux[demux_index].demux_fd[num].fd = 0;
1331 return 1; // all ok!
1334 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)
1336 int32_t o;
1337 for(o = 0; o < maxfilter; o++) // check if filter is present
1339 if(demux[demux_id].demux_fd[o].fd > 0 &&
1340 demux[demux_id].demux_fd[o].pid == pid &&
1341 demux[demux_id].demux_fd[o].type == type &&
1342 demux[demux_id].demux_fd[o].filter[0] == table &&
1343 demux[demux_id].demux_fd[o].mask[0] == mask
1346 return;
1349 uchar filter[32];
1350 memset(filter, 0, 32);
1352 filter[0] = table;
1353 filter[16] = mask;
1355 cs_log_dbg(D_DVBAPI, "Demuxer %d try to start new filter for caid: %04X, provid: %06X, pid: %04X", demux_id, caid, provid, pid);
1356 dvbapi_set_filter(demux_id, selected_api, pid, caid, provid, filter, filter + 16, timeout, pidindex, type, 0);
1359 void dvbapi_start_sdt_filter(int32_t demux_index)
1361 dvbapi_start_filter(demux_index, demux[demux_index].pidindex, 0x11, 0x001, 0x01, 0x42, 0xFF, 0, TYPE_SDT);
1362 demux[demux_index].sdt_filter = 0;
1365 void dvbapi_start_pat_filter(int32_t demux_index)
1367 dvbapi_start_filter(demux_index, demux[demux_index].pidindex, 0x00, 0x001, 0x01, 0x00, 0xFF, 0, TYPE_PAT);
1370 void dvbapi_start_pmt_filter(int32_t demux_index, int32_t pmt_pid)
1372 uchar filter[16], mask[16];
1373 memset(filter, 0, 16);
1374 memset(mask, 0, 16);
1376 filter[0] = 0x02;
1377 i2b_buf(2, demux[demux_index].program_number, filter + 1); // add srvid to filter since the pid can deliver pmt for multiple srvid
1378 mask[0] = 0xFF;
1379 mask[1] = 0xFF;
1380 mask[2] = 0xFF;
1381 dvbapi_set_filter(demux_index, selected_api, pmt_pid, 0x001, 0x01, filter, mask, 0, 0, TYPE_PMT, 0);
1384 void dvbapi_start_emm_filter(int32_t demux_index)
1386 unsigned int j;
1387 if(!demux[demux_index].EMMpidcount)
1388 { return; }
1390 //if (demux[demux_index].emm_filter)
1391 // return;
1394 struct s_csystem_emm_filter *dmx_filter = NULL;
1395 unsigned int filter_count = 0;
1396 uint16_t caid, ncaid;
1397 uint32_t provid;
1399 struct s_reader *rdr = NULL;
1400 struct s_client *cl = cur_client();
1401 if(!cl || !cl->aureader_list)
1402 { return; }
1404 LL_ITER itr = ll_iter_create(cl->aureader_list);
1405 while((rdr = ll_iter_next(&itr)))
1407 if(!(rdr->grp & cl->grp))
1408 { continue; }
1409 if(rdr->audisabled || !rdr->enable || (!is_network_reader(rdr) && rdr->card_status != CARD_INSERTED))
1410 { continue; }
1412 const struct s_cardsystem *csystem;
1413 uint16_t c, match;
1414 cs_log_dbg(D_DVBAPI, "Demuxer %d matching reader %s against available emmpids -> START!", demux_index, rdr->label);
1415 for(c = 0; c < demux[demux_index].EMMpidcount; c++)
1417 caid = ncaid = demux[demux_index].EMMpids[c].CAID;
1418 if(!caid) continue;
1420 if(chk_is_betatunnel_caid(caid) == 2)
1422 ncaid = tunemm_caid_map(FROM_TO, caid, demux[demux_index].program_number);
1424 provid = demux[demux_index].EMMpids[c].PROVID;
1425 if (caid == ncaid)
1427 match = emm_reader_match(rdr, caid, provid);
1429 else
1431 match = emm_reader_match(rdr, ncaid, provid);
1433 if(match)
1435 csystem = get_cardsystem_by_caid(caid);
1436 if(csystem)
1438 if(caid != ncaid)
1440 csystem = get_cardsystem_by_caid(ncaid);
1441 if(csystem && csystem->get_tunemm_filter)
1443 csystem->get_tunemm_filter(rdr, &dmx_filter, &filter_count);
1444 cs_log_dbg(D_DVBAPI, "Demuxer %d setting emm filter for betatunnel: %04X -> %04X", demux_index, ncaid, caid);
1446 else
1448 cs_log_dbg(D_DVBAPI, "Demuxer %d cardsystem for emm filter for caid %04X of reader %s not found", demux_index, ncaid, rdr->label);
1449 continue;
1452 else if (csystem->get_emm_filter)
1454 csystem->get_emm_filter(rdr, &dmx_filter, &filter_count);
1457 else
1459 cs_log_dbg(D_DVBAPI, "Demuxer %d cardsystem for emm filter for caid %04X of reader %s not found", demux_index, caid, rdr->label);
1460 continue;
1463 for(j = 0; j < filter_count ; j++)
1465 if(dmx_filter[j].enabled == 0)
1466 { continue; }
1468 uchar filter[32];
1469 memset(filter, 0, sizeof(filter)); // reset filter
1470 uint32_t usefilterbytes = 16; // default use all filters
1471 memcpy(filter, dmx_filter[j].filter, usefilterbytes);
1472 memcpy(filter + 16, dmx_filter[j].mask, usefilterbytes);
1473 int32_t emmtype = dmx_filter[j].type;
1475 if(filter[0] && (((1 << (filter[0] % 0x80)) & rdr->b_nano) && !((1 << (filter[0] % 0x80)) & rdr->s_nano)))
1477 cs_log_dbg(D_DVBAPI, "Demuxer %d reader %s emmfilter %d/%d blocked by userconfig -> SKIP!", demux_index, rdr->label, j+1, filter_count);
1478 continue;
1481 if((rdr->blockemm & emmtype) && !(((1 << (filter[0] % 0x80)) & rdr->s_nano) || (rdr->saveemm & emmtype)))
1483 cs_log_dbg(D_DVBAPI, "Demuxer %d reader %s emmfilter %d/%d blocked by userconfig -> SKIP!", demux_index, rdr->label, j+1, filter_count);
1484 continue;
1487 if(demux[demux_index].EMMpids[c].type & emmtype)
1489 cs_log_dbg(D_DVBAPI, "Demuxer %d reader %s emmfilter %d/%d type match -> ENABLE!", demux_index, rdr->label, j+1, filter_count);
1490 check_add_emmpid(demux_index, filter, c, emmtype);
1492 else
1494 cs_log_dbg(D_DVBAPI, "Demuxer %d reader %s emmfilter %d/%d type mismatch -> SKIP!", demux_index, rdr->label, j+1, filter_count);
1498 // dmx_filter not use below this point;
1499 NULLFREE(dmx_filter);
1500 filter_count = 0;
1503 cs_log_dbg(D_DVBAPI, "Demuxer %d matching reader %s against available emmpids -> DONE!", demux_index, rdr->label);
1505 if(demux[demux_index].emm_filter == -1) // first run -1
1507 demux[demux_index].emm_filter = 0;
1509 cs_log_dbg(D_DVBAPI, "Demuxer %d handles %i emm filters", demux_index, demux[demux_index].emm_filter);
1512 void dvbapi_add_ecmpid_int(int32_t demux_id, uint16_t caid, uint16_t ecmpid, uint32_t provid, char *txt)
1514 int32_t n, added = 0;
1516 if(demux[demux_id].ECMpidcount >= ECM_PIDS)
1517 { return; }
1519 int32_t stream = demux[demux_id].STREAMpidcount - 1;
1520 for(n = 0; n < demux[demux_id].ECMpidcount; n++)
1522 if(stream > -1 && demux[demux_id].ECMpids[n].CAID == caid && demux[demux_id].ECMpids[n].ECM_PID == ecmpid && demux[demux_id].ECMpids[n].PROVID == provid)
1524 if(!demux[demux_id].ECMpids[n].streams)
1526 //we already got this caid/ecmpid as global, no need to add the single stream
1527 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);
1528 continue;
1530 added = 1;
1531 demux[demux_id].ECMpids[n].streams |= (1 << stream);
1532 cs_log("Demuxer %d added stream to ecmpid %d CAID: %04X ECM_PID: %04X PROVID: %06X", demux_id, n, caid, ecmpid, provid);
1536 if(added == 1)
1537 { return; }
1538 for(n = 0; n < demux[demux_id].ECMpidcount; n++) // check for existing pid
1540 if(demux[demux_id].ECMpids[n].CAID == caid && demux[demux_id].ECMpids[n].ECM_PID == ecmpid && demux[demux_id].ECMpids[n].PROVID == provid)
1541 { return; } // found same pid -> skip
1543 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].ECM_PID = ecmpid;
1544 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CAID = caid;
1545 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].PROVID = provid;
1546 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CHID = 0x10000; // reset CHID
1547 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].checked = 0;
1548 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].status = 0;
1549 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].tries = 0xFE;
1550 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].streams = 0; // reset streams!
1551 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].irdeto_curindex = 0xFE; // reset
1552 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].irdeto_maxindex = 0; // reset
1553 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].irdeto_cycle = 0xFE; // reset
1554 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].table = 0;
1556 cs_log("Demuxer %d ecmpid %d CAID: %04X ECM_PID: %04X PROVID: %06X %s", demux_id, demux[demux_id].ECMpidcount, caid, ecmpid, provid, txt);
1557 if(caid_is_irdeto(caid)) { demux[demux_id].emmstart.time = 1; } // marker to fetch emms early irdeto needs them!
1559 demux[demux_id].ECMpidcount++;
1562 void dvbapi_add_ecmpid(int32_t demux_id, uint16_t caid, uint16_t ecmpid, uint32_t provid, char *txt)
1564 dvbapi_add_ecmpid_int(demux_id, caid, ecmpid, provid, txt);
1565 struct s_dvbapi_priority *joinentry;
1567 for(joinentry = dvbapi_priority; joinentry != NULL; joinentry = joinentry->next)
1569 if((joinentry->type != 'j')
1570 || (joinentry->caid && joinentry->caid != caid)
1571 || (joinentry->provid && joinentry->provid != provid)
1572 || (joinentry->ecmpid && joinentry->ecmpid != ecmpid)
1573 || (joinentry->srvid && joinentry->srvid != demux[demux_id].program_number))
1574 { continue; }
1575 cs_log_dbg(D_DVBAPI, "Join ecmpid %04X@%06X:%04X to %04X@%06X:%04X",
1576 caid, provid, ecmpid, joinentry->mapcaid, joinentry->mapprovid, joinentry->mapecmpid);
1577 dvbapi_add_ecmpid_int(demux_id, joinentry->mapcaid, joinentry->mapecmpid, joinentry->mapprovid, txt);
1581 void dvbapi_add_emmpid(int32_t demux_id, uint16_t caid, uint16_t emmpid, uint32_t provid, uint8_t type)
1583 char typetext[40];
1584 cs_strncpy(typetext, ":", sizeof(typetext));
1586 if(type & 0x01) { strcat(typetext, "UNIQUE:"); }
1587 if(type & 0x02) { strcat(typetext, "SHARED:"); }
1588 if(type & 0x04) { strcat(typetext, "GLOBAL:"); }
1589 if(type & 0xF8) { strcat(typetext, "UNKNOWN:"); }
1591 uint16_t i;
1592 for(i = 0; i < demux[demux_id].EMMpidcount; i++)
1594 if(demux[demux_id].EMMpids[i].PID == emmpid && demux[demux_id].EMMpids[i].CAID == caid && demux[demux_id].EMMpids[i].PROVID == provid)
1596 if(!(demux[demux_id].EMMpids[i].type&type)){
1597 demux[demux_id].EMMpids[i].type |= type; // register this emm kind to this emmpid
1598 cs_log_dbg(D_DVBAPI, "Added to existing emmpid %d additional emmtype %s", demux[demux_id].EMMpidcount - 1, typetext);
1600 return;
1603 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].PID = emmpid;
1604 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].CAID = caid;
1605 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].PROVID = provid;
1606 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount++].type = type;
1607 cs_log_dbg(D_DVBAPI, "Added new emmpid %d CAID: %04X EMM_PID: %04X PROVID: %06X TYPE %s", demux[demux_id].EMMpidcount - 1, caid, emmpid, provid, typetext);
1610 void dvbapi_parse_cat(int32_t demux_id, uchar *buf, int32_t len)
1612 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
1613 // driver sometimes reports error if too many emm filter
1614 // but adding more ecm filter is no problem
1615 // ... so ifdef here instead of limiting MAX_FILTER
1616 demux[demux_id].max_emm_filter = 14;
1617 #else
1618 if(cfg.dvbapi_requestmode == 1)
1620 uint16_t ecm_filter_needed = 0, n;
1621 for(n = 0; n < demux[demux_id].ECMpidcount; n++)
1623 if(demux[demux_id].ECMpids[n].status > -1)
1624 { ecm_filter_needed++; }
1626 if(maxfilter - ecm_filter_needed <= 0)
1627 { demux[demux_id].max_emm_filter = 0; }
1628 else
1629 { demux[demux_id].max_emm_filter = maxfilter - ecm_filter_needed; }
1631 else
1633 demux[demux_id].max_emm_filter = maxfilter - 1;
1635 #endif
1636 uint16_t i, k;
1638 cs_log_dump_dbg(D_DVBAPI, buf, len, "cat:");
1640 for(i = 8; i < (b2i(2, buf + 1)&0xFFF) - 1; i += buf[i + 1] + 2)
1642 if(buf[i] != 0x09) { continue; }
1643 if(demux[demux_id].EMMpidcount >= ECM_PIDS) { break; }
1645 uint16_t caid = b2i(2, buf + i + 2);
1646 uint16_t emm_pid = b2i(2, buf + i +4)&0x1FFF;
1647 uint32_t emm_provider = 0;
1649 switch(caid >> 8)
1651 case 0x01:
1652 dvbapi_add_emmpid(demux_id, caid, emm_pid, 0, EMM_UNIQUE | EMM_GLOBAL);
1653 for(k = i + 7; k < i + buf[i + 1] + 2; k += 4)
1655 emm_provider = b2i(2, buf + k + 2);
1656 emm_pid = b2i(2, buf + k)&0xFFF;
1657 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, EMM_SHARED);
1659 break;
1660 case 0x05:
1661 for(k = i + 6; k < i + buf[i + 1] + 2; k += buf[k + 1] + 2)
1663 if (buf[k] == 0x14)
1665 emm_provider = (b2i(3, buf + k + 2) & 0xFFFFF0); // viaccess fixup last digit is a dont care!
1666 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1669 break;
1670 case 0x18:
1671 if(buf[i + 1] == 0x07 || buf[i + 1] == 0x0B)
1673 for(k = i + 7; k < i + 7 + buf[i + 6]; k += 2)
1675 emm_provider = b2i(2, buf + k);
1676 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1679 else
1681 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1683 break;
1684 default:
1685 dvbapi_add_emmpid(demux_id, caid, emm_pid, 0, EMM_UNIQUE | EMM_SHARED | EMM_GLOBAL);
1686 break;
1689 return;
1692 ca_index_t dvbapi_get_descindex(int32_t demux_index, int32_t pid, int32_t stream_id)
1694 int32_t i, j, k, fail = 1;
1695 ca_index_t idx = 0;
1696 uint32_t tmp_idx;
1698 static pthread_mutex_t lockindex;
1699 static int8_t init_mutex = 0;
1701 if(init_mutex == 0)
1703 SAFE_MUTEX_INIT(&lockindex, NULL);
1704 init_mutex = 1;
1707 if(cfg.dvbapi_boxtype == BOXTYPE_NEUMO)
1709 tmp_idx = 0;
1710 sscanf(demux[demux_index].pmt_file, "pmt%3d.tmp", &tmp_idx);
1711 return (ca_index_t)tmp_idx;
1714 SAFE_MUTEX_LOCK(&lockindex); // to avoid race when readers become responsive!
1716 while(fail && idx <= INDEX_MAX)
1718 fail = 0;
1719 for(i = 0; i < MAX_DEMUX && !fail && idx <= INDEX_MAX; i++)
1721 if(demux[i].program_number == 0) { continue; } // skip empty demuxers
1723 if(demux[i].ca_mask != demux[demux_index].ca_mask && (!(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)))
1725 continue; // skip demuxer using other ca device
1728 for(j = 0; j < demux[i].ECMpidcount && !fail; j++) // search for new unique index
1730 for(k = 0; k < MAX_STREAM_INDICES; k++)
1732 if(demux[i].ECMpids[j].index[k] == idx)
1734 fail = 1;
1735 idx++;
1742 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
1744 if(idx > INDEX_MAX_NET)
1746 idx = INDEX_INVALID;
1749 else
1751 if(idx > INDEX_MAX_LOCAL)
1753 idx = INDEX_INVALID;
1757 demux[demux_index].ECMpids[pid].index[stream_id] = idx;
1759 SAFE_MUTEX_UNLOCK(&lockindex); // and release it!
1761 return idx;
1764 void dvbapi_set_pid(int32_t demux_id, int32_t num, ca_index_t idx, bool enable, bool use_des)
1766 int32_t i, currentfd;
1767 ca_index_t newidx = 0, curidx;
1769 if(demux[demux_id].pidindex == -1 && enable) return; // no current pid on enable? --> exit
1771 switch(selected_api)
1773 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
1774 case STAPI:
1775 if(!enable) idx = INDEX_INVALID;
1776 stapi_set_pid(demux_id, num, idx, demux[demux_id].STREAMpids[num], demux[demux_id].pmt_file); // only used to disable pids!!!
1777 break;
1778 #endif
1779 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
1780 case COOLAPI:
1781 break;
1782 #endif
1783 default:
1784 for(i = 0; i < MAX_DEMUX; i++)
1786 newidx = INDEX_INVALID, curidx = idx;
1787 if(((demux[demux_id].ca_mask & (1 << i)) == (uint32_t) (1 << i)))
1789 uint32_t action = 0;
1790 if(enable){
1791 action = update_streampid_list(i, demux[demux_id].STREAMpids[num], curidx, use_des);
1793 if(!enable){
1794 action = remove_streampid_from_list(i, demux[demux_id].STREAMpids[num], curidx);
1797 if(action != NO_STREAMPID_LISTED && action != INVALID_STREAMPID_INDEX && action != FOUND_STREAMPID_INDEX && action != ADDED_STREAMPID_INDEX)
1799 ca_pid_t ca_pid2;
1800 memset(&ca_pid2, 0, sizeof(ca_pid2));
1801 ca_pid2.pid = demux[demux_id].STREAMpids[num];
1803 // removed last of this streampid on ca? -> disable this pid with -1 on this ca
1804 if((action == REMOVED_STREAMPID_LASTINDEX) && (is_ca_used(i, ca_pid2.pid) == INDEX_INVALID)) curidx = DVBAPI_INDEX_DISABLE;
1806 // removed index of streampid that is used to decode on ca -> get a fresh one
1807 if(action == REMOVED_DECODING_STREAMPID_INDEX)
1809 newidx = is_ca_used(i, demux[demux_id].STREAMpids[num]); // get an active index for this pid and enable it on ca device
1810 curidx = DVBAPI_INDEX_DISABLE;
1813 while (curidx != INDEX_INVALID || newidx != INDEX_INVALID)
1815 if(curidx != INDEX_INVALID)
1817 (curidx == DVBAPI_INDEX_DISABLE) ? (ca_pid2.index = -1) : (ca_pid2.index = curidx);
1818 cs_log_dbg(D_DVBAPI, "Demuxer %d %s stream %d pid=0x%04x index=%d on ca%d", demux_id,
1819 (enable ? "enable" : "disable"), num + 1, ca_pid2.pid, ca_pid2.index, i);
1820 curidx = INDEX_INVALID; // flag this index as handled
1822 else if (newidx != INDEX_INVALID)
1824 (newidx == DVBAPI_INDEX_DISABLE) ? (ca_pid2.index = -1) : (ca_pid2.index = newidx);
1825 cs_log_dbg(D_DVBAPI, "Demuxer %d takeover stream %d pid=0x%04x by index=%d on ca%d", demux_id, num + 1,
1826 ca_pid2.pid, ca_pid2.index, i);
1827 newidx = INDEX_INVALID; // flag this takeover / new index as handled
1830 if(use_des && cfg.dvbapi_extended_cw_api == 2 && ca_pid2.index != -1)
1832 ca_pid2.index |= 0x100;
1835 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
1836 dvbapi_net_send(DVBAPI_CA_SET_PID, demux[demux_id].socket_fd, demux_id, -1 /*unused*/, (unsigned char *) &ca_pid2, NULL, NULL, demux[demux_id].client_proto_version);
1837 else
1839 currentfd = ca_fd[i];
1840 if(currentfd <= 0)
1842 currentfd = dvbapi_open_device(1, i, demux[demux_id].adapter_index);
1843 ca_fd[i] = currentfd; // save fd of this ca
1845 if(currentfd > 0)
1847 if(dvbapi_ioctl(currentfd, CA_SET_PID, &ca_pid2) == -1)
1849 cs_log_dbg(D_TRACE | D_DVBAPI,"CA_SET_PID ioctl error (errno=%d %s)", errno, strerror(errno));
1850 remove_streampid_from_list(i, ca_pid2.pid, INDEX_DISABLE_ALL);
1853 ca_index_t result = is_ca_used(i,0); // check if in use by any pid
1855 if(result == INDEX_INVALID)
1857 cs_log_dbg(D_DVBAPI, "Demuxer %d close now unused CA%d device", demux_id, i);
1858 int32_t ret = close(currentfd);
1859 if(ret < 0) { cs_log("ERROR: Could not close demuxer fd (errno=%d %s)", errno, strerror(errno)); }
1860 currentfd = ca_fd[i] = 0;
1868 break;
1870 return;
1873 void dvbapi_stop_all_descrambling(void)
1875 int32_t j;
1876 for(j = 0; j < MAX_DEMUX; j++)
1878 if(demux[j].program_number == 0) { continue; }
1879 dvbapi_stop_descrambling(j);
1883 void dvbapi_stop_all_emm_sdt_filtering(void)
1885 int32_t j;
1886 for(j = 0; j < MAX_DEMUX; j++)
1888 if(demux[j].program_number == 0) { continue; }
1889 dvbapi_stop_filter(j, TYPE_EMM);
1890 dvbapi_stop_filter(j, TYPE_SDT);
1891 demux[j].emm_filter = -1;
1896 void dvbapi_stop_descrambling(int32_t demux_id)
1898 int32_t i, j, z;
1899 if(demux[demux_id].program_number == 0) { return; }
1900 char channame[CS_SERVICENAME_SIZE];
1901 i = demux[demux_id].pidindex;
1902 if(i < 0) { i = 0; }
1903 demux[demux_id].pidindex = -1; // no ecmpid is to be descrambling since we start stop descrambling!
1904 get_servicename(dvbapi_client, demux[demux_id].program_number, demux[demux_id].ECMpidcount > 0 ? demux[demux_id].ECMpids[i].PROVID : 0, demux[demux_id].ECMpidcount > 0 ? demux[demux_id].ECMpids[i].CAID : 0, channame, sizeof(channame));
1905 cs_log_dbg(D_DVBAPI, "Demuxer %d stop descrambling program number %04X (%s)", demux_id, demux[demux_id].program_number, channame);
1907 dvbapi_stop_filter(demux_id, TYPE_EMM);
1908 dvbapi_stop_filter(demux_id, TYPE_SDT);
1909 dvbapi_stop_filter(demux_id, TYPE_PAT);
1910 dvbapi_stop_filter(demux_id, TYPE_PMT);
1912 for(i = 0; i < demux[demux_id].ECMpidcount && demux[demux_id].ECMpidcount > 0; i++)
1914 for(j = 0; j < MAX_STREAM_INDICES; j++)
1916 if(demux[demux_id].ECMpids[i].index[j] == INDEX_INVALID) continue;
1918 // disable streams!
1919 for(z = 0; z < demux[demux_id].STREAMpidcount; z++)
1921 dvbapi_set_pid(demux_id, z, demux[demux_id].ECMpids[i].index[j], false, false); // disable streampid
1923 demux[demux_id].ECMpids[i].index[j] = INDEX_INVALID;
1926 dvbapi_stop_filter(demux_id, TYPE_ECM);
1928 memset(&demux[demux_id], 0 , sizeof(DEMUXTYPE));
1929 for(i = 0; i < ECM_PIDS; i++)
1931 for(j = 0; j < MAX_STREAM_INDICES; j++)
1933 demux[demux_id].ECMpids[i].index[j] = INDEX_INVALID;
1937 demux[demux_id].pidindex = -1;
1938 demux[demux_id].curindex = -1;
1939 if (!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX)
1940 unlink(ECMINFO_FILE);
1941 return;
1944 int32_t dvbapi_start_descrambling(int32_t demux_id, int32_t pid, int8_t checked)
1946 int32_t started = 0; // in case ecmfilter started = 1
1947 int32_t fake_ecm = 0;
1948 ECM_REQUEST *er;
1949 struct s_reader *rdr;
1950 if(!(er = get_ecmtask())) { return started; }
1951 demux[demux_id].ECMpids[pid].checked = checked + 1; // mark this pid as checked!
1953 struct s_dvbapi_priority *p;
1954 for(p = dvbapi_priority; p != NULL ; p = p->next)
1956 if((p->type != 'p')
1957 || (p->caid && p->caid != demux[demux_id].ECMpids[pid].CAID)
1958 || (p->provid && p->provid != demux[demux_id].ECMpids[pid].PROVID)
1959 || (p->ecmpid && p->ecmpid != demux[demux_id].ECMpids[pid].ECM_PID)
1960 || (p->srvid && p->srvid != demux[demux_id].program_number)
1961 || (p->pidx && p->pidx-1 != pid))
1962 { continue; }
1963 // if found chid and first run apply chid filter, on forced pids always apply!
1964 if(p->type == 'p' && p->chid < 0x10000 && (demux[demux_id].ECMpids[pid].checked == 1 || (p && p->force)))
1966 if(demux[demux_id].ECMpids[pid].CHID < 0x10000) // channelcache delivered chid
1968 er->chid = demux[demux_id].ECMpids[pid].CHID;
1970 else
1972 er->chid = p->chid; // no channelcache or no chid in use, so use prio chid
1973 demux[demux_id].ECMpids[pid].CHID = p->chid;
1975 //cs_log("********* CHID %04X **************", demux[demux_id].ECMpids[pid].CHID);
1976 break; // we only accept one!
1978 else
1980 if(demux[demux_id].ECMpids[pid].CHID < 0x10000) // channelcache delivered chid
1982 er->chid = demux[demux_id].ECMpids[pid].CHID;
1984 else // no channelcache or no chid in use
1986 er->chid = 0;
1987 demux[demux_id].ECMpids[pid].CHID = 0x10000;
1991 er->srvid = demux[demux_id].program_number;
1992 er->caid = demux[demux_id].ECMpids[pid].CAID;
1993 er->pid = demux[demux_id].ECMpids[pid].ECM_PID;
1994 er->prid = demux[demux_id].ECMpids[pid].PROVID;
1995 er->vpid = demux[demux_id].ECMpids[pid].VPID;
1996 er->pmtpid = demux[demux_id].pmtpid;
1998 #ifdef WITH_STAPI5
1999 cs_strncpy(er->dev_name, dev_list[demux[demux_id].dev_index].name, sizeof(dev_list[demux[demux_id].dev_index].name));
2000 #endif
2002 struct timeb now;
2003 cs_ftime(&now);
2004 for(rdr = first_active_reader; rdr != NULL ; rdr = rdr->next)
2006 int8_t match = matching_reader(er, rdr); // check for matching reader
2007 int64_t gone = comp_timeb(&now, &rdr->emm_last);
2008 if(gone > 3600*1000 && rdr->needsemmfirst && caid_is_irdeto(er->caid))
2010 cs_log("Warning reader %s received no emms for the last %d seconds -> skip, this reader needs emms first!", rdr->label,
2011 (int)(gone/1000));
2012 continue; // skip this card needs to process emms first before it can be used for descramble
2014 if(p && p->force) { match = 1; } // forced pid always started!
2016 if(!match) // if this reader does not match, check betatunnel for it
2017 match = lb_check_auto_betatunnel(er, rdr);
2019 if(!match && chk_is_betatunnel_caid(er->caid)) // these caids might be tunneled invisible by peers
2020 { match = 1; } // so make it a match to try it!
2022 if(config_enabled(CS_CACHEEX) && (!match && (cacheex_is_match_alias(dvbapi_client, er)))) // check if cache-ex is matching
2024 match = 1; // so make it a match to try it!
2027 // BISS or FAKE CAID
2028 // ecm stream pid is fake, so send out one fake ecm request
2029 // special treatment: if we asked the cw first without starting a filter the cw request will be killed due to no ecmfilter started
2030 if(caid_is_fake(demux[demux_id].ECMpids[pid].CAID) || caid_is_biss(demux[demux_id].ECMpids[pid].CAID))
2032 int32_t j, n;
2033 er->ecmlen = 5;
2034 er->ecm[0] = 0x80; // to pass the cache check it must be 0x80 or 0x81
2035 er->ecm[1] = 0x00;
2036 er->ecm[2] = 0x02;
2037 i2b_buf(2, er->srvid, er->ecm + 3);
2039 for(j = 0, n = 5; j < demux[demux_id].STREAMpidcount; j++, n += 2)
2041 i2b_buf(2, demux[demux_id].STREAMpids[j], er->ecm + n);
2042 er->ecm[2] += 2;
2043 er->ecmlen += 2;
2046 cs_log("Demuxer %d trying to descramble PID %d CAID %04X PROVID %06X ECMPID %04X ANY CHID PMTPID %04X VPID %04X", demux_id, pid,
2047 demux[demux_id].ECMpids[pid].CAID, demux[demux_id].ECMpids[pid].PROVID, demux[demux_id].ECMpids[pid].ECM_PID,
2048 demux[demux_id].pmtpid, demux[demux_id].ECMpids[pid].VPID);
2050 demux[demux_id].curindex = pid; // set current pid to the fresh started one
2052 dvbapi_start_filter(demux_id, pid, demux[demux_id].ECMpids[pid].ECM_PID, demux[demux_id].ECMpids[pid].CAID,
2053 demux[demux_id].ECMpids[pid].PROVID, 0x80, 0xF0, 3000, TYPE_ECM);
2054 started = 1;
2056 request_cw(dvbapi_client, er, demux_id, 0); // do not register ecm since this try!
2057 fake_ecm = 1;
2058 break; // we started an ecmfilter so stop looking for next matching reader!
2060 if(match) // if matching reader found check for irdeto cas if local irdeto card check if it received emms in last 60 minutes
2063 if(caid_is_irdeto(er->caid)) // irdeto cas init irdeto_curindex to wait for first index (00)
2065 if(demux[demux_id].ECMpids[pid].irdeto_curindex == 0xFE) { demux[demux_id].ECMpids[pid].irdeto_curindex = 0x00; }
2068 if(p && p->chid < 0x10000) // do we prio a certain chid?
2070 cs_log("Demuxer %d trying to descramble PID %d CAID %04X PROVID %06X ECMPID %04X CHID %04X PMTPID %04X VPID %04X", demux_id, pid,
2071 demux[demux_id].ECMpids[pid].CAID, demux[demux_id].ECMpids[pid].PROVID, demux[demux_id].ECMpids[pid].ECM_PID,
2072 demux[demux_id].ECMpids[pid].CHID, demux[demux_id].pmtpid, demux[demux_id].ECMpids[pid].VPID);
2074 else
2076 cs_log("Demuxer %d trying to descramble PID %d CAID %04X PROVID %06X ECMPID %04X ANY CHID PMTPID %04X VPID %04X", demux_id, pid,
2077 demux[demux_id].ECMpids[pid].CAID, demux[demux_id].ECMpids[pid].PROVID, demux[demux_id].ECMpids[pid].ECM_PID,
2078 demux[demux_id].pmtpid, demux[demux_id].ECMpids[pid].VPID);
2081 demux[demux_id].curindex = pid; // set current pid to the fresh started one
2083 dvbapi_start_filter(demux_id, pid, demux[demux_id].ECMpids[pid].ECM_PID, demux[demux_id].ECMpids[pid].CAID,
2084 demux[demux_id].ECMpids[pid].PROVID, 0x80, 0xF0, 3000, TYPE_ECM);
2085 started = 1;
2086 break; // we started an ecmfilter so stop looking for next matching reader!
2089 if(demux[demux_id].curindex != pid)
2091 cs_log("Demuxer %d impossible to descramble PID %d CAID %04X PROVID %06X ECMPID %04X PMTPID %04X (NO MATCHING READER)", demux_id, pid,
2092 demux[demux_id].ECMpids[pid].CAID, demux[demux_id].ECMpids[pid].PROVID, demux[demux_id].ECMpids[pid].ECM_PID, demux[demux_id].pmtpid);
2093 demux[demux_id].ECMpids[pid].checked = 4; // flag this pid as checked
2094 demux[demux_id].ECMpids[pid].status = -1; // flag this pid as unusable
2095 dvbapi_edit_channel_cache(demux_id, pid, 0); // remove this pid from channelcache
2097 if(!fake_ecm) { NULLFREE(er); }
2098 return started;
2101 struct s_dvbapi_priority *dvbapi_check_prio_match_emmpid(int32_t demux_id, uint16_t caid, uint32_t provid, char type)
2103 struct s_dvbapi_priority *p;
2104 int32_t i;
2106 uint16_t ecm_pid = 0;
2107 for(i = 0; i < demux[demux_id].ECMpidcount; i++)
2109 if((demux[demux_id].ECMpids[i].CAID == caid) && (demux[demux_id].ECMpids[i].PROVID == provid))
2111 ecm_pid = demux[demux_id].ECMpids[i].ECM_PID;
2112 break;
2116 if(!ecm_pid)
2117 { return NULL; }
2119 for(p = dvbapi_priority; p != NULL; p = p->next)
2121 if(p->type != type
2122 || (p->caid && p->caid != caid)
2123 || (p->provid && p->provid != provid)
2124 || (p->ecmpid && p->ecmpid != ecm_pid)
2125 || (p->srvid && p->srvid != demux[demux_id].program_number)
2126 || (p->pidx && p->pidx-1 !=i)
2127 || (p->type == 'i' && (p->chid < 0x10000)))
2128 { continue; }
2129 return p;
2131 return NULL;
2134 struct s_dvbapi_priority *dvbapi_check_prio_match(int32_t demux_id, int32_t pidindex, char type)
2136 if(!dvbapi_priority)
2138 return NULL;
2140 struct s_dvbapi_priority *p;
2141 struct s_ecmpids *ecmpid = &demux[demux_id].ECMpids[pidindex];
2143 for(p = dvbapi_priority; p != NULL; p = p->next)
2145 if(p->type != type
2146 || (p->caid && p->caid != ecmpid->CAID)
2147 || (p->provid && p->provid != ecmpid->PROVID)
2148 || (p->ecmpid && p->ecmpid != ecmpid->ECM_PID)
2149 || (p->srvid && p->srvid != demux[demux_id].program_number)
2150 || (p->pidx && p->pidx-1 != pidindex)
2151 || (p->chid < 0x10000 && p->chid != ecmpid->CHID))
2152 { continue; }
2153 return p;
2155 return NULL;
2158 void dvbapi_process_emm(int32_t demux_index, int32_t filter_num, unsigned char *buffer, uint32_t len)
2160 EMM_PACKET epg;
2162 struct s_emm_filter *filter = get_emmfilter_by_filternum(demux_index, filter_num+1); // 0 is used for pending emmfilters, so everything increase 1
2164 if(!filter)
2166 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d no filter matches -> SKIP!", demux_index, filter_num +1);
2167 return;
2170 uint32_t provider = filter->provid;
2171 uint16_t caid = filter->caid;
2173 struct s_dvbapi_priority *mapentry = dvbapi_check_prio_match_emmpid(filter->demux_id, filter->caid, filter->provid, 'm');
2174 if(mapentry)
2176 cs_log_dbg(D_DVBAPI, "Demuxer %d mapping EMM from %04X@%06X to %04X@%06X", demux_index, caid, provider, mapentry->mapcaid,
2177 mapentry->mapprovid);
2178 caid = mapentry->mapcaid;
2179 provider = mapentry->mapprovid;
2182 memset(&epg, 0, sizeof(epg));
2184 i2b_buf(2, caid, epg.caid);
2185 i2b_buf(4, provider, epg.provid);
2187 epg.emmlen = len > sizeof(epg.emm) ? sizeof(epg.emm) : len;
2188 memcpy(epg.emm, buffer, epg.emmlen);
2190 if(config_enabled(READER_IRDETO) && chk_is_betatunnel_caid(caid) == 2)
2192 uint16_t ncaid = tunemm_caid_map(FROM_TO, caid, demux[demux_index].program_number);
2193 if(caid != ncaid)
2195 irdeto_add_emm_header(&epg);
2196 i2b_buf(2, ncaid, epg.caid);
2200 do_emm(dvbapi_client, &epg);
2203 void dvbapi_read_priority(void)
2205 FILE *fp;
2206 char token[128], str1[128];
2207 char type;
2208 int32_t i, ret, count = 0;
2210 const char *cs_prio = "oscam.dvbapi";
2212 fp = fopen(get_config_filename(token, sizeof(token), cs_prio), "r");
2214 if(!fp)
2216 cs_log_dbg(D_DVBAPI, "ERROR: Can't open priority file %s", token);
2217 return;
2220 if(dvbapi_priority)
2222 cs_log_dbg(D_DVBAPI, "reread priority file %s", cs_prio);
2223 struct s_dvbapi_priority *o, *p;
2224 for(p = dvbapi_priority; p != NULL; p = o)
2226 o = p->next;
2227 NULLFREE(p);
2229 dvbapi_priority = NULL;
2232 while(fgets(token, sizeof(token), fp))
2234 // Ignore comments and empty lines
2235 if(token[0] == '#' || token[0] == '/' || token[0] == '\n' || token[0] == '\r' || token[0] == '\0')
2236 { continue; }
2237 if(strlen(token) > 100) { continue; }
2239 memset(str1, 0, 128);
2241 for(i = 0; i < (int)strlen(token) && token[i] == ' '; i++) { ; }
2242 if(i == (int)strlen(token) - 1) //empty line or all spaces
2243 { continue; }
2245 for(i = 0; i < (int)strlen(token); i++)
2247 if(token[i] == '@')
2249 token[i] = ':';
2253 for(i = 0; i < (int)strlen(token); i++)
2255 if((token[i] == ':' || token[i] == ' ') && token[i + 1] == ':') // if "::" or " :"
2257 memmove(token + i + 2, token + i + 1, strlen(token) - i + 1); //insert extra position
2258 token[i + 1] = '0'; //and fill it with NULL
2260 if(token[i] == '#' || token[i] == '/')
2262 token[i] = '\0';
2263 break;
2267 type = 0;
2268 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
2269 uint32_t disablefilter = 0;
2270 ret = sscanf(trim(token), "%c: %63s %63s %d", &type, str1, str1 + 64, &disablefilter);
2271 #else
2272 ret = sscanf(trim(token), "%c: %63s %63s", &type, str1, str1 + 64);
2273 #endif
2274 type = tolower((uchar)type);
2276 if(ret < 1 || (type != 'p' && type != 'i' && type != 'm' && type != 'd' && type != 's' && type != 'l'
2277 && type != 'j' && type != 'a' && type != 'x'))
2279 //fprintf(stderr, "Warning: line containing %s in %s not recognized, ignoring line\n", token, cs_prio);
2280 //fprintf would issue the warning to the command line, which is more consistent with other config warnings
2281 //however it takes OSCam a long time (>4 seconds) to reach this part of the program, so the warnings are reaching tty rather late
2282 //which leads to confusion. So send the warnings to log file instead
2283 cs_log_dbg(D_DVBAPI, "WARN: line containing %s in %s not recognized, ignoring line\n", token, cs_prio);
2284 continue;
2287 struct s_dvbapi_priority *entry;
2288 if(!cs_malloc(&entry, sizeof(struct s_dvbapi_priority)))
2290 ret = fclose(fp);
2291 if(ret < 0) { cs_log("ERROR: Could not close oscam.dvbapi fd (errno=%d %s)", errno, strerror(errno)); }
2292 return;
2295 entry->type = type;
2296 entry->next = NULL;
2298 count++;
2300 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
2301 if(type == 's')
2303 strncpy(entry->devname, str1, 29);
2304 strncpy(entry->pmtfile, str1 + 64, 29);
2306 entry->disablefilter = disablefilter;
2308 cs_log_dbg(D_DVBAPI, "stapi prio: ret=%d | %c: %s %s | disable %d",
2309 ret, type, entry->devname, entry->pmtfile, disablefilter);
2311 if(!dvbapi_priority)
2313 dvbapi_priority = entry;
2315 else
2317 struct s_dvbapi_priority *p;
2318 for(p = dvbapi_priority; p->next != NULL; p = p->next) { ; }
2319 p->next = entry;
2321 continue;
2323 #endif
2325 char c_srvid[34];
2326 c_srvid[0] = '\0';
2327 uint32_t caid = 0, provid = 0, srvid = 0, ecmpid = 0;
2328 uint32_t chid = 0x10000; //chid=0 is a valid chid
2329 ret = sscanf(str1, "%4x:%6x:%33[^:]:%4x:%4x"SCNx16, &caid, &provid, c_srvid, &ecmpid, &chid);
2330 if(ret < 1)
2332 cs_log("Error in oscam.dvbapi: ret=%d | %c: %04X %06X %s %04X %04X",
2333 ret, type, caid, provid, c_srvid, ecmpid, chid);
2334 continue; // skip this entry!
2336 else
2338 cs_log_dbg(D_DVBAPI, "Parsing rule: ret=%d | %c: %04X %06X %s %04X %04X",
2339 ret, type, caid, provid, c_srvid, ecmpid, chid);
2342 entry->caid = caid;
2343 entry->provid = provid;
2344 entry->ecmpid = ecmpid;
2345 entry->chid = chid;
2347 uint32_t delay = 0, force = 0, mapcaid = 0, mapprovid = 0, mapecmpid = 0, pidx = 0;
2348 switch(type)
2350 case 'i':
2351 ret = sscanf(str1 + 64, "%1d", &pidx);
2352 entry->pidx = pidx+1;
2353 if(ret < 1) entry->pidx = 0;
2354 break;
2355 case 'd':
2356 sscanf(str1 + 64, "%4d", &delay);
2357 entry->delay = delay;
2358 break;
2359 case 'l':
2360 entry->delay = dyn_word_atob(str1 + 64);
2361 if(entry->delay == -1) { entry->delay = 0; }
2362 break;
2363 case 'p':
2364 ret = sscanf(str1 + 64, "%1d:%1d", &force, &pidx);
2365 entry->force = force;
2366 entry->pidx = pidx+1;
2367 if(ret < 2) entry->pidx = 0;
2368 break;
2369 case 'm':
2370 sscanf(str1 + 64, "%4x:%6x", &mapcaid, &mapprovid);
2371 if(!mapcaid) { mapcaid = 0xFFFF; }
2372 entry->mapcaid = mapcaid;
2373 entry->mapprovid = mapprovid;
2374 break;
2375 case 'a':
2376 case 'j':
2377 sscanf(str1 + 64, "%4x:%6x:%4x", &mapcaid, &mapprovid, &mapecmpid);
2378 if(!mapcaid) { mapcaid = 0xFFFF; }
2379 entry->mapcaid = mapcaid;
2380 entry->mapprovid = mapprovid;
2381 entry->mapecmpid = mapecmpid;
2382 break;
2385 if(c_srvid[0] == '=')
2387 struct s_srvid *this;
2389 for(i = 0; i < 16; i++)
2390 for(this = cfg.srvid[i]; this != NULL; this = this->next)
2392 if(this->name && strcmp(this->name, c_srvid + 1) == 0)
2394 struct s_dvbapi_priority *entry2;
2395 if(!cs_malloc(&entry2, sizeof(struct s_dvbapi_priority)))
2396 { continue; }
2397 memcpy(entry2, entry, sizeof(struct s_dvbapi_priority));
2399 entry2->srvid = this->srvid;
2401 cs_log_dbg(D_DVBAPI, "prio srvid: ret=%d | %c: %04X %06X %04X %04X %04X -> map %04X %06X %04X | prio %d | delay %d",
2402 ret, entry2->type, entry2->caid, entry2->provid, entry2->srvid, entry2->ecmpid, entry2->chid,
2403 entry2->mapcaid, entry2->mapprovid, entry2->mapecmpid, entry2->force, entry2->delay);
2405 if(!dvbapi_priority)
2407 dvbapi_priority = entry2;
2409 else
2411 struct s_dvbapi_priority *p;
2412 for(p = dvbapi_priority; p->next != NULL; p = p->next) { ; }
2413 p->next = entry2;
2417 NULLFREE(entry);
2418 continue;
2420 else
2422 sscanf(c_srvid, "%4x", &srvid);
2423 entry->srvid = srvid;
2426 cs_log_dbg(D_DVBAPI, "prio: ret=%d | %c: %04X %06X %04X %04X %04X -> map %04X %06X %04X | prio %d | delay %d",
2427 ret, entry->type, entry->caid, entry->provid, entry->srvid, entry->ecmpid, entry->chid, entry->mapcaid,
2428 entry->mapprovid, entry->mapecmpid, entry->force, entry->delay);
2430 if(!dvbapi_priority)
2432 dvbapi_priority = entry;
2434 else
2436 struct s_dvbapi_priority *p;
2437 for(p = dvbapi_priority; p->next != NULL; p = p->next) { ; }
2438 p->next = entry;
2442 cs_log_dbg(D_DVBAPI, "Read %d entries from %s", count, cs_prio);
2444 ret = fclose(fp);
2445 if(ret < 0) { cs_log("ERROR: Could not close oscam.dvbapi fd (errno=%d %s)", errno, strerror(errno)); }
2446 return;
2449 void dvbapi_resort_ecmpids(int32_t demux_index)
2451 int32_t n, cache = 0, matching_done = 0, found = -1, match_reader_count = 0, total_reader = 0;
2452 uint16_t btun_caid = 0;
2453 struct timeb start,end;
2454 cs_ftime(&start);
2455 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2457 demux[demux_index].ECMpids[n].status = 0;
2458 demux[demux_index].ECMpids[n].checked = 0;
2459 demux[demux_index].ECMpids[n].irdeto_curindex = 0xFE;
2460 demux[demux_index].ECMpids[n].irdeto_maxindex = 0;
2461 demux[demux_index].ECMpids[n].irdeto_cycle = 0xFE;
2462 demux[demux_index].ECMpids[n].tries = 0xFE;
2463 demux[demux_index].ECMpids[n].table = 0;
2466 demux[demux_index].max_status = 0;
2467 demux[demux_index].curindex = -1;
2468 demux[demux_index].pidindex = -1;
2471 struct s_reader *rdr;
2473 int32_t p_order = demux[demux_index].ECMpidcount+1;
2474 struct s_dvbapi_priority *prio;
2476 // handle prio order in oscam.dvbapi + ignore all chids
2478 for(rdr = first_active_reader; rdr ; rdr = rdr->next)
2480 total_reader++; // only need to calculate once!
2483 ECM_REQUEST *er;
2484 if(!cs_malloc(&er, sizeof(ECM_REQUEST)))
2485 { return; }
2487 for(prio = dvbapi_priority; prio != NULL; prio = prio->next)
2489 if(prio->type != 'p' && prio->type != 'i' )
2490 { continue; }
2491 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2493 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2494 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
2495 er->prid = demux[demux_index].ECMpids[n].PROVID;
2496 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
2497 er->srvid = demux[demux_index].program_number;
2498 er->client = cur_client();
2499 btun_caid = chk_on_btun(SRVID_MASK, er->client, er);
2500 if(prio->type == 'p' && btun_caid)
2502 er->caid = btun_caid;
2505 if(prio->caid && (prio->caid != er->caid && prio->caid != er->ocaid)) { continue; }
2506 if(prio->provid && prio->provid != er->prid) { continue; }
2507 if(prio->srvid && prio->srvid != er->srvid) { continue; }
2508 if(prio->ecmpid && prio->ecmpid != er->pid) { continue; }
2509 if(prio->pidx && prio->pidx-1 != n) { continue; }
2511 if(prio->type == 'p') // check for prio
2513 if(prio->chid < 0x10000) { demux[demux_index].ECMpids[n].CHID = prio->chid; }
2514 if(prio->force)
2516 int32_t j;
2517 for(j = 0; j < demux[demux_index].ECMpidcount; j++)
2519 demux[demux_index].ECMpids[j].status = -1;
2521 demux[demux_index].ECMpids[n].status = 1;
2522 demux[demux_index].ECMpids[n].checked = 0;
2523 demux[demux_index].max_status = 1;
2524 demux[demux_index].max_emm_filter = maxfilter - 1;
2525 cs_log_dbg(D_DVBAPI, "Demuxer %d prio forced%s ecmpid %d %04X@%06X:%04X:%04X (file)", demux_index,
2526 ((prio->caid == er->caid && prio->caid != er->ocaid) ? " betatunneled" : ""), n, demux[demux_index].ECMpids[n].CAID,
2527 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, (uint16_t) prio->chid);
2528 NULLFREE(er);
2529 return; // go start descrambling since its forced by user!
2531 else
2533 if(!demux[demux_index].ECMpids[n].status) // only accept first matching prio from oscam.dvbapi
2535 demux[demux_index].ECMpids[n].status = total_reader + p_order--;
2536 matching_done = 1;
2537 cs_log_dbg(D_DVBAPI, "Demuxer %d prio%s ecmpid %d %04X@%06X:%04X:%04X weight: %d (file)", demux_index,
2538 ((prio->caid == er->caid && prio->caid != er->ocaid) ? " betatunneled" : ""), n, demux[demux_index].ECMpids[n].CAID,
2539 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, (uint16_t) prio->chid, demux[demux_index].ECMpids[n].status);
2541 continue; // evaluate next ecmpid
2544 if(prio->type == 'i' && prio->chid == 0x10000 && demux[demux_index].ECMpids[n].status == 0) // check for ignore all chids
2546 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,
2547 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID);
2548 demux[demux_index].ECMpids[n].status = -1;
2549 continue; // evaluate next ecmpid
2554 p_order = demux[demux_index].ECMpidcount+1;
2556 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2558 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2560 int32_t nr;
2561 SIDTAB *sidtab;
2562 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
2563 er->prid = demux[demux_index].ECMpids[n].PROVID;
2564 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
2565 er->srvid = demux[demux_index].program_number;
2566 er->client = cur_client();
2567 btun_caid = chk_on_btun(SRVID_MASK, er->client, er);
2569 if(btun_caid)
2571 er->caid = btun_caid;
2574 match_reader_count = 0;
2575 for(rdr = first_active_reader; rdr ; rdr = rdr->next)
2577 if(matching_reader(er, rdr))
2579 match_reader_count++;
2583 if(match_reader_count == 0)
2585 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,
2586 demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].ECM_PID, demux[demux_index].ECMpids[n].CHID);
2587 demux[demux_index].ECMpids[n].status = -1;
2588 continue; // evaluate next ecmpid
2590 else
2592 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
2594 if(sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid)
2596 if((cfg.dvbapi_sidtabs.no & ((SIDTABBITS)1 << nr)) && (chk_srvid_match(er, sidtab)))
2598 demux[demux_index].ECMpids[n].status = -1; //ignore
2599 cs_log_dbg(D_DVBAPI, "Demuxer %d ignore ecmpid %d %04X@%06X:%04X (service %s pos %d)", demux_index,
2600 n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID,
2601 demux[demux_index].ECMpids[n].ECM_PID, sidtab->label, nr);
2602 continue; // evaluate next ecmpid
2604 if((cfg.dvbapi_sidtabs.ok & ((SIDTABBITS)1 << nr)) && (chk_srvid_match(er, sidtab)))
2606 demux[demux_index].ECMpids[n].status++; //priority
2607 cs_log_dbg(D_DVBAPI, "Demuxer %d prio ecmpid %d %04X@%06X:%04X weight: %d (service %s pos %d)", demux_index,
2608 n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID,
2609 demux[demux_index].ECMpids[n].ECM_PID, demux[demux_index].ECMpids[n].status, sidtab->label,nr);
2615 // ecmpids with no matching readers are disabled and matching sidtabbits have now highest status
2618 // ecmpid with highest prio from oscam.dvbapi has now highest status
2620 // check all ecmpids and get the highest amount cache-ex and local readers
2621 int32_t max_local_matching_reader = 0, max_cacheex_reader = 0;
2622 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2624 int32_t count_matching_cacheex_reader = 0, count_matching_local_reader = 0;
2626 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2628 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
2629 er->prid = demux[demux_index].ECMpids[n].PROVID;
2630 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
2631 er->srvid = demux[demux_index].program_number;
2632 er->client = cur_client();
2633 btun_caid = chk_on_btun(SRVID_MASK, er->client, er);
2635 if(btun_caid)
2637 er->caid = btun_caid;
2640 for(rdr = first_active_reader; rdr ; rdr = rdr->next)
2642 if(matching_reader(er, rdr))
2644 if(cacheex_reader(rdr))
2646 count_matching_cacheex_reader++;
2648 else if(is_localreader(rdr, er))
2650 count_matching_local_reader++;
2655 if(max_local_matching_reader < count_matching_local_reader)
2657 max_local_matching_reader = count_matching_local_reader;
2659 if(max_cacheex_reader < count_matching_cacheex_reader)
2661 max_cacheex_reader = count_matching_cacheex_reader;
2665 if(max_local_matching_reader != 0 || max_cacheex_reader != 0)
2667 p_order = demux[demux_index].ECMpidcount*2;
2669 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2671 int32_t count_matching_cacheex_reader = 0, count_matching_local_reader = 0;
2672 int32_t localprio = 1, cacheexprio = 1;
2674 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2676 if(cfg.preferlocalcards == 2) // ecmpids with local reader get highest prio
2678 localprio = max_cacheex_reader+p_order+1;
2680 else if(cfg.preferlocalcards == 1) // ecmpids with cacheex reader get highest prio
2682 cacheexprio = max_local_matching_reader+p_order+1;
2685 er->caid = er->ocaid = demux[demux_index].ECMpids[n].CAID;
2686 er->prid = demux[demux_index].ECMpids[n].PROVID;
2687 er->pid = demux[demux_index].ECMpids[n].ECM_PID;
2688 er->srvid = demux[demux_index].program_number;
2689 er->client = cur_client();
2690 btun_caid = chk_on_btun(SRVID_MASK, er->client, er);
2692 if(btun_caid)
2694 er->caid = btun_caid;
2696 int32_t oldstatus = demux[demux_index].ECMpids[n].status;
2697 int32_t anyreader = 0;
2698 for(rdr = first_active_reader; rdr ; rdr = rdr->next)
2700 if(matching_reader(er, rdr))
2702 if(cfg.preferlocalcards == 0)
2704 if(!matching_done) {demux[demux_index].ECMpids[n].status++;}
2705 anyreader++;
2706 continue;
2708 if(cacheex_reader(rdr))
2710 demux[demux_index].ECMpids[n].status += cacheexprio;
2711 count_matching_cacheex_reader++;
2712 cacheexprio=1;
2714 if(is_localreader(rdr, er))
2716 demux[demux_index].ECMpids[n].status += localprio;
2717 count_matching_local_reader++;
2718 localprio=1;
2723 if(oldstatus != demux[demux_index].ECMpids[n].status)
2725 if(anyreader)
2727 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,
2728 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);
2730 else
2732 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,
2733 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,
2734 count_matching_local_reader, count_matching_cacheex_reader);
2740 struct s_channel_cache *c = NULL;
2742 for(n = 0; n < demux[demux_index].ECMpidcount && matching_done == 0; n++)
2744 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2746 c = dvbapi_find_channel_cache(demux_index, n, 0); // find exact channel match
2747 if(c != NULL)
2749 found = n;
2750 cache = 2; //found cache entry with higher priority
2751 demux[demux_index].ECMpids[n].status++; // prioritize CAIDs which already decoded same caid:provid:srvid
2752 if(c->chid < 0x10000) { demux[demux_index].ECMpids[n].CHID = c->chid; } // if chid registered in cache -> use it!
2753 cs_log_dbg(D_DVBAPI, "Demuxer %d prio ecmpid %d %04X@%06X:%04X weight: %d (found caid/provid/srvid in cache)", demux_index, n,
2754 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);
2755 break;
2759 if(found == -1)
2761 // prioritize CAIDs which already decoded same caid:provid
2762 for(n = 0; n < demux[demux_index].ECMpidcount && matching_done == 0; n++)
2764 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2766 c = dvbapi_find_channel_cache(demux_index, n, 1);
2767 if(c != NULL)
2769 cache = 1; //found cache entry
2770 demux[demux_index].ECMpids[n].status++;
2771 cs_log_dbg(D_DVBAPI, "Demuxer %d prio ecmpid %d %04X@%06X:%04X weight: %d (found caid/provid in cache)", demux_index, n,
2772 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);
2777 int32_t max_status = 0;
2778 int32_t highest_priopid = -1;
2780 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2782 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2784 if(demux[demux_index].ECMpids[n].status > max_status) // find highest prio pid
2786 max_status = demux[demux_index].ECMpids[n].status;
2787 highest_priopid = n;
2789 if(!USE_OPENXCAS) // openxcas doesnt use prio and non-prio run: all are equal!
2791 if(demux[demux_index].ECMpids[n].status == 0) { demux[demux_index].ECMpids[n].checked = 2; } // set pids with no status to no prio run
2795 demux[demux_index].max_status = max_status; // register maxstatus
2796 if(highest_priopid != -1 && found == highest_priopid && cache == 2) // Found entry in channelcache that is valid and has exact match on srvid
2798 for(n = 0; n < demux[demux_index].ECMpidcount; n++)
2800 if(demux[demux_index].ECMpids[n].status == -1) continue; // skip ignores!
2802 if(n != found)
2804 // disable non matching pid
2805 demux[demux_index].ECMpids[n].status = -1;
2807 else
2809 demux[demux_index].ECMpids[n].status = 1;
2812 demux[demux_index].max_emm_filter = maxfilter - 1;
2813 demux[demux_index].max_status = 1;
2814 cs_log("Demuxer %d found channel in cache and matching prio -> start descrambling ecmpid %d ", demux_index, found);
2817 NULLFREE(er);
2819 cs_ftime(&end);
2820 int64_t gone = comp_timeb(&end, &start);
2821 cs_log_dbg(D_DVBAPI, "Demuxer %d sorting the ecmpids took %"PRId64" ms", demux_index, gone);
2822 return;
2825 void dvbapi_parse_descriptor(int32_t demux_id, uint32_t info_length, unsigned char *buffer, uint8_t* is_audio)
2827 // int32_t ca_pmt_cmd_id = buffer[i + 5];
2828 uint32_t descriptor_length = 0;
2829 uint32_t j, u, k;
2830 uint8_t skip_border = cfg.dvbapi_boxtype == BOXTYPE_SAMYGO ? 0x05 : 0x02; // skip input values <0x05 on samygo
2832 static const char format_identifiers_audio[10][5] =
2834 "AC-3", "BSSD", "dmat", "DTS1", "DTS2",
2835 "DTS3", "EAC3", "HDMV", "mlpa", "Opus",
2838 if(info_length < 1)
2839 { return; }
2841 if((buffer[0] < skip_border) && info_length > 0) // skip input values like 0x00 and 0x01
2843 buffer++;
2844 info_length--;
2847 for(j = 0; j + 1 < info_length; j += descriptor_length + 2)
2849 descriptor_length = buffer[j + 1];
2851 if(is_audio)
2853 if(buffer[j] == 0x6A || buffer[j] == 0x73 || buffer[j] == 0x81)
2855 *is_audio = 1;
2857 else if(buffer[j] == 0x05 && descriptor_length >= 4)
2859 for(k = 0; k < 10; k++)
2861 if(memcmp(buffer + j + 2, format_identifiers_audio[k], 4) == 0)
2863 *is_audio = 1;
2864 break;
2870 if(buffer[j] == 0x81 && descriptor_length == 8) // private descriptor of length 8, assume enigma/tvh
2872 demux[demux_id].enigma_namespace = b2i(4, buffer + j + 2);
2873 demux[demux_id].tsid = b2i(2, buffer + j + 6);
2874 demux[demux_id].onid = b2i(2, buffer + j + 8);
2875 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,
2876 buffer[j], descriptor_length, demux[demux_id].enigma_namespace, demux[demux_id].tsid, demux[demux_id].onid);
2878 else if (descriptor_length !=0)
2880 cs_log_dbg(D_TRACE, "Demuxer %d found pmt type: %02x length: %d", demux_id, buffer[j], descriptor_length);
2883 if(buffer[j] != 0x09) { continue; }
2885 if(demux[demux_id].ECMpidcount >= ECM_PIDS) { break; }
2887 int32_t descriptor_ca_system_id = b2i(2, buffer + j + 2);
2888 int32_t descriptor_ca_pid = b2i(2, buffer + j + 4)&0x1FFF;
2889 int32_t descriptor_ca_provider = 0;
2890 char txt[40]; // room for PBM: 8 byte pbm and DATE: date
2891 memset(txt, 0x00, sizeof(txt));
2893 if(descriptor_ca_system_id >> 8 == 0x01)
2895 for(u = 2; u < descriptor_length; u += 15)
2897 descriptor_ca_pid = b2i(2, buffer + j + u + 2)&0x1FFF;
2898 descriptor_ca_provider = b2i(2, buffer + j + u + 4);
2899 int8_t year = buffer[j + u + 15] >> 1;
2900 int8_t month = (((buffer[j + u + 15]&0x01) << 3) | (buffer[j + u + 16] >> 5));
2901 int8_t day = buffer[j + u + 16]&0x1F;
2902 snprintf(txt, sizeof(txt), "PBM: ");
2903 cs_hexdump(0, buffer + j + u + 7, 8, txt+5, (2*8)+1); // hexdump 8 byte pbm
2904 snprintf(txt+20, sizeof(txt)-20, " DATE: %d-%d-%d", day, month, year+1990);
2905 dvbapi_add_ecmpid(demux_id, descriptor_ca_system_id, descriptor_ca_pid, descriptor_ca_provider, txt);
2908 else
2910 if(caid_is_viaccess(descriptor_ca_system_id) && descriptor_length == 0x0F && buffer[j + 12] == 0x14)
2911 { descriptor_ca_provider = b2i(3, buffer + j + 14) &0xFFFFF0; }
2913 if(caid_is_nagra(descriptor_ca_system_id) && descriptor_length == 0x07)
2914 { descriptor_ca_provider = b2i(2, buffer + j + 7); }
2916 if((descriptor_ca_system_id >> 8 == 0x4A || descriptor_ca_system_id == 0x2710) && descriptor_length > 0x04 )
2917 { descriptor_ca_provider = buffer[j + 6]; }
2919 dvbapi_add_ecmpid(demux_id, descriptor_ca_system_id, descriptor_ca_pid, descriptor_ca_provider, txt);
2924 // Apply mapping:
2925 if(dvbapi_priority)
2927 struct s_dvbapi_priority *mapentry;
2928 for(j = 0; (int32_t)j < demux[demux_id].ECMpidcount; j++)
2930 mapentry = dvbapi_check_prio_match(demux_id, j, 'm');
2931 if(mapentry)
2933 cs_log_dbg(D_DVBAPI, "Demuxer %d mapping ecmpid %d from %04X@%06X to %04X@%06X", demux_id, j,
2934 demux[demux_id].ECMpids[j].CAID, demux[demux_id].ECMpids[j].PROVID,
2935 mapentry->mapcaid, mapentry->mapprovid);
2936 demux[demux_id].ECMpids[j].CAID = mapentry->mapcaid;
2937 demux[demux_id].ECMpids[j].PROVID = mapentry->mapprovid;
2943 void request_cw(struct s_client *client, ECM_REQUEST *er, int32_t demux_id, uint8_t delayed_ecm_check)
2945 if(!er)
2947 return;
2951 int32_t filternum = dvbapi_set_section_filter(demux_id, er, -1); // set ecm filter to odd -> even and visaversa
2952 if(filternum < 0)
2954 cs_log_dbg(D_DVBAPI, "Demuxer %d not requesting cw -> ecm filter was killed!", demux_id);
2955 NULLFREE(er);
2956 return;
2959 if(!delayed_ecm_check) // no delayed ecm check for this filter
2961 memset(demux[demux_id].demux_fd[filternum].lastecmd5, 0, CS_ECMSTORESIZE); // no ecm delay check: zero it!
2963 else
2965 unsigned char md5tmp[MD5_DIGEST_LENGTH];
2966 MD5(er->ecm, er->ecmlen, md5tmp);
2967 if(!memcmp(demux[demux_id].demux_fd[filternum].prevecmd5, md5tmp, CS_ECMSTORESIZE))
2969 if(demux[demux_id].demux_fd[filternum].prevresult < E_NOTFOUND)
2971 cs_log_dbg(D_DVBAPI, "Demuxer %d not requesting same ecm again! -> SKIP!", demux_id);
2972 NULLFREE(er);
2973 return;
2975 else
2977 cs_log_dbg(D_DVBAPI, "Demuxer %d requesting same ecm again (previous result was not found!)", demux_id);
2980 else if(!memcmp(demux[demux_id].demux_fd[filternum].lastecmd5, md5tmp, CS_ECMSTORESIZE))
2982 if(demux[demux_id].demux_fd[filternum].lastresult < E_NOTFOUND)
2984 cs_log_dbg(D_DVBAPI, "Demuxer %d not requesting same ecm again! -> SKIP!", demux_id);
2985 NULLFREE(er);
2986 return;
2988 else
2990 cs_log_dbg(D_DVBAPI, "Demuxer %d requesting same ecm again (previous result was not found!)", demux_id);
2993 memcpy(demux[demux_id].demux_fd[filternum].prevecmd5, demux[demux_id].demux_fd[filternum].lastecmd5, CS_ECMSTORESIZE);
2994 demux[demux_id].demux_fd[filternum].prevresult = demux[demux_id].demux_fd[filternum].lastresult;
2995 memcpy(demux[demux_id].demux_fd[filternum].lastecmd5, md5tmp, CS_ECMSTORESIZE);
2996 demux[demux_id].demux_fd[filternum].lastresult = 0xFF;
2999 cs_log_dbg(D_DVBAPI, "Demuxer %d get controlword!", demux_id);
3000 get_cw(client, er);
3002 #ifdef WITH_DEBUG
3003 char buf[ECM_FMT_LEN];
3004 format_ecm(er, buf, ECM_FMT_LEN);
3005 cs_log_dbg(D_DVBAPI, "Demuxer %d request controlword for ecm %s", demux_id, buf);
3006 #endif
3009 void dvbapi_try_next_caid(int32_t demux_id, int8_t checked)
3012 int32_t n, j, found = -1, started = 0;
3014 int32_t status = demux[demux_id].max_status;
3016 for(j = status; j >= 0; j--) // largest status first!
3019 for(n = 0; n < demux[demux_id].ECMpidcount; n++)
3021 //cs_log_dbg(D_DVBAPI,"Demuxer %d PID %d checked = %d status = %d (searching for pid with status = %d)", demux_id, n,
3022 // demux[demux_id].ECMpids[n].checked, demux[demux_id].ECMpids[n].status, j);
3023 if(demux[demux_id].ECMpids[n].checked == checked && demux[demux_id].ECMpids[n].status == j)
3025 found = n;
3027 openxcas_set_provid(demux[demux_id].ECMpids[found].PROVID);
3028 openxcas_set_caid(demux[demux_id].ECMpids[found].CAID);
3029 openxcas_set_ecm_pid(demux[demux_id].ECMpids[found].ECM_PID);
3031 // fixup for cas that need emm first!
3032 if(caid_is_irdeto(demux[demux_id].ECMpids[found].CAID)) { demux[demux_id].emmstart.time = 0; }
3033 started = dvbapi_start_descrambling(demux_id, found, checked);
3034 if(cfg.dvbapi_requestmode == 0 && started == 1) { return; } // in requestmode 0 we only start 1 ecm request at the time
3039 if(found == -1 && demux[demux_id].pidindex == -1)
3041 cs_log("Demuxer %d no suitable readers found that can be used for decoding!", demux_id);
3042 return;
3046 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)
3048 *ca_mask = 0x01, *demux_index = 0x00, *adapter_index = 0x00, *pmtpid = 0x00;
3050 if(buffer[17] == 0x82 && buffer[18] == 0x02)
3052 // enigma2
3053 *ca_mask = buffer[19];
3054 uint32_t demuxid = buffer[20];
3055 if (demuxid == 0xff) demuxid = 0; // tryfix prismcube (0xff -> "demux-1" = error! )
3056 *demux_index = demuxid;
3057 if (buffer[21]==0x84 && buffer[22]==0x02) *pmtpid = b2i(2, buffer+23);
3058 if (buffer[25]==0x83 && buffer[26]==0x01) *adapter_index=buffer[27]; // from code cahandler.cpp 0x83 index of adapter
3061 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX_PMT)
3063 *ca_mask = demux_id + 1;
3064 *demux_index = demux_id;
3067 if(cfg.dvbapi_boxtype == BOXTYPE_QBOXHD && buffer[17] == 0x82 && buffer[18] == 0x03)
3069 // ca_mask = buffer[19]; // with STONE 1.0.4 always 0x01
3070 *demux_index = buffer[20]; // with STONE 1.0.4 always 0x00
3071 *adapter_index = buffer[21]; // with STONE 1.0.4 adapter index can be 0,1,2
3072 *ca_mask = (1 << *adapter_index); // use adapter_index as ca_mask (used as index for ca_fd[] array)
3075 if((cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX || cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
3076 && buffer[7] == 0x82 && buffer[8] == 0x02)
3078 *demux_index = buffer[9]; // it is always 0 but you never know
3079 *adapter_index = buffer[10]; // adapter index can be 0,1,2
3080 *ca_mask = (1 << *adapter_index); // use adapter_index as ca_mask (used as index for ca_fd[] array)
3084 static void dvbapi_capmt_notify(struct demux_s *dmx)
3086 struct s_client *cl;
3087 for(cl = first_client->next; cl ; cl = cl->next)
3089 if((cl->typ == 'p' || cl->typ == 'r') && cl->reader && cl->reader->ph.c_capmt)
3091 struct demux_s *curdemux;
3092 if(cs_malloc(&curdemux, sizeof(struct demux_s)))
3094 memcpy(curdemux, dmx, sizeof(struct demux_s));
3095 add_job(cl, ACTION_READER_CAPMT_NOTIFY, curdemux, sizeof(struct demux_s));
3101 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)
3103 uint32_t i = 0, start_descrambling = 0;
3104 int32_t j = 0;
3105 int32_t demux_id = -1;
3106 uint16_t demux_index, adapter_index, pmtpid;
3107 uint32_t ca_mask;
3108 uint32_t program_number, program_info_length;
3109 uint8_t program_info_start = is_real_pmt ? 12 : 6;
3111 if(!is_real_pmt)
3114 #define LIST_MORE 0x00 //*CA application should append a 'MORE' CAPMT object to the list and start receiving the next object
3115 #define LIST_FIRST 0x01 //*CA application should clear the list when a 'FIRST' CAPMT object is received, and start receiving the next object
3116 #define LIST_LAST 0x02 //*CA application should append a 'LAST' CAPMT object to the list and start working with the list
3117 #define LIST_ONLY 0x03 //*CA application should clear the list when an 'ONLY' CAPMT object is received, and start working with the object
3118 #define LIST_ADD 0x04 //*CA application should append an 'ADD' CAPMT object to the current list and start working with the updated list
3119 #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
3121 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
3122 int32_t ca_pmt_list_management = LIST_ONLY;
3123 #else
3124 int32_t ca_pmt_list_management = buffer[0];
3125 #endif
3126 program_number = b2i(2, buffer + 1);
3127 program_info_length = b2i(2, buffer + 4) &0xFFF;
3129 cs_log_dump_dbg(D_DVBAPI, buffer, length, "capmt:");
3130 cs_log_dbg(D_DVBAPI, "Receiver sends PMT command %d for channel %04X", ca_pmt_list_management, program_number);
3132 if(!pmt_stopmarking && (ca_pmt_list_management == LIST_FIRST || ca_pmt_list_management == LIST_ONLY))
3134 for(i = 0; i < MAX_DEMUX; i++)
3136 if(demux[i].program_number == 0) { continue; } // skip empty demuxers
3137 if(demux[i].socket_fd != connfd) { continue; } // skip demuxers belonging to other ca pmt connection
3138 if((demux[i].socket_fd == -1) && (pmtfile && strcmp(demux[i].pmt_file, pmtfile) != 0)) { continue; } // skip demuxers handled by other pmt files
3139 demux[i].stopdescramble = 1; // Mark for deletion if not used again by following pmt objects.
3140 cs_log_dbg(D_DVBAPI, "Marked demuxer %d/%d (srvid = %04X fd = %d) to stop decoding", i, MAX_DEMUX, demux[i].program_number, connfd);
3142 pmt_stopmarking = 1; // only stop demuxing for first pmt record
3145 getDemuxOptions(i, buffer, &ca_mask, &demux_index, &adapter_index, &pmtpid);
3146 cs_log_dbg(D_DVBAPI,"Receiver wants to demux srvid %04X on adapter %04X camask %04X index %04X pmtpid %04X",
3147 program_number, adapter_index, ca_mask, demux_index, pmtpid);
3149 for(i = 0; i < MAX_DEMUX; i++) // search current demuxers for running the same program as the one we received in this PMT object
3151 if(demux[i].program_number == 0) { continue; }
3152 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX_PMT) demux_index = i; // fixup for ipbox
3154 bool full_check = 1, matched = 0;
3155 if (config_enabled(WITH_COOLAPI) || config_enabled(WITH_COOLAPI2) || cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
3156 full_check = 0;
3158 if (full_check)
3159 matched = (connfd > 0 && demux[i].socket_fd == connfd) && demux[i].program_number == program_number;
3160 else
3161 matched = connfd > 0 && demux[i].program_number == program_number;
3163 if(matched)
3165 if (full_check) {
3166 if (demux[i].adapter_index != adapter_index) continue; // perhaps next demuxer matches?
3167 if (demux[i].ca_mask != ca_mask) continue; // perhaps next demuxer matches?
3168 if (demux[i].demux_index != demux_index) continue; // perhaps next demuxer matches?
3170 if(ca_pmt_list_management == LIST_UPDATE){
3171 cs_log("Demuxer %d PMT update for decoding of SRVID %04X! ", i, program_number);
3174 demux_id = i;
3176 cs_log("Demuxer %d continue decoding of SRVID %04X", i, demux[i].program_number);
3178 openxcas_set_sid(program_number);
3180 demux[i].stopdescramble = 0; // dont stop current demuxer!
3181 break; // no need to explore other demuxers since we have a found!
3185 // start using the new list
3186 if(ca_pmt_list_management != LIST_FIRST && ca_pmt_list_management != LIST_MORE)
3188 for(j = 0; j < MAX_DEMUX; j++)
3190 if(demux[j].program_number == 0) { continue; }
3191 if(demux[j].stopdescramble == 1) { dvbapi_stop_descrambling(j); }// Stop descrambling and remove all demuxer entries not in new PMT.
3193 start_descrambling = 1; // flag that demuxer descrambling is to be executed!
3194 pmt_stopmarking = 0; // flag that demuxers may be marked for stop decoding again
3197 if(demux_id == -1)
3199 for(demux_id = 0; demux_id < MAX_DEMUX && demux[demux_id].program_number > 0; demux_id++) { ; }
3202 if(demux_id >= MAX_DEMUX)
3204 cs_log("ERROR: No free id (MAX_DEMUX)");
3205 return -1;
3208 demux[demux_id].program_number = program_number; // do this early since some prio items use them!
3209 demux[demux_id].enigma_namespace = 0;
3210 demux[demux_id].tsid = 0;
3211 demux[demux_id].onid = 0;
3212 demux[demux_id].pmtpid = pmtpid;
3213 demux[demux_id].socket_fd = connfd;
3214 demux[demux_id].adapter_index = adapter_index;
3215 demux[demux_id].client_proto_version = client_proto_version;
3217 if(pmtfile)
3219 cs_strncpy(demux[demux_id].pmt_file, pmtfile, sizeof(demux[demux_id].pmt_file));
3222 if(pmtpid)
3224 dvbapi_start_pmt_filter(demux_id, pmtpid);
3226 else
3228 dvbapi_start_pat_filter(demux_id);
3231 if(demux[demux_id].running == 0) demux[demux_id].ECMpidcount = 0; // reset number of ecmpids only if it was not running!
3233 else // is_real_pmt
3235 demux_id = existing_demux_id;
3237 dvbapi_stop_filter(demux_id, TYPE_PMT);
3239 program_number = b2i(2, buffer + 3);
3240 program_info_length = b2i(2, buffer + 10) &0xFFF;
3242 cs_log_dump_dbg(D_DVBAPI, buffer, length, "pmt:");
3243 pmtpid = demux[demux_id].pmtpid;
3246 for(j = 0; j < demux[demux_id].ECMpidcount; j++) // cleanout demuxer from possible stale info
3248 demux[demux_id].ECMpids[j].streams = 0; // reset streams of each ecmpid!
3250 demux[demux_id].STREAMpidcount = 0; // reset number of streams
3252 if(program_info_length > 1 && program_info_length < length)
3254 dvbapi_parse_descriptor(demux_id, program_info_length - 1, buffer + program_info_start, NULL);
3257 uint32_t es_info_length = 0, vpid = 0;
3258 struct s_dvbapi_priority *addentry;
3260 for(i = program_info_length + program_info_start; i + 4 < length; i += es_info_length + 5)
3262 uint8_t stream_type = buffer[i];
3263 uint16_t elementary_pid = b2i(2, buffer + i + 1)&0x1FFF;
3264 uint8_t is_audio = 0;
3265 es_info_length = b2i(2, buffer + i +3)&0x0FFF;
3267 if(demux[demux_id].STREAMpidcount >= ECM_PIDS)
3269 break;
3272 demux[demux_id].STREAMpids[demux[demux_id].STREAMpidcount] = elementary_pid;
3273 demux[demux_id].STREAMpidsType[demux[demux_id].STREAMpidcount] = buffer[i];
3274 demux[demux_id].STREAMpidcount++;
3276 cs_log("Demuxer %d stream %s(type: %02x pid: %04x length: %d)", demux_id, get_streamtxt(stream_type), stream_type, elementary_pid, es_info_length);
3278 // find and register videopid
3279 if(!vpid &&
3280 (stream_type == 0x01 || stream_type == 0x02 || stream_type == 0x10 || stream_type == 0x1B
3281 || stream_type == 0x24 || stream_type == 0x42 || stream_type == 0xD1 || stream_type == 0xEA))
3283 vpid = elementary_pid;
3286 if(es_info_length != 0 && es_info_length < length)
3288 dvbapi_parse_descriptor(demux_id, es_info_length, buffer + i + 5, &is_audio);
3290 if((stream_type == 0x06 || stream_type == 0x80 || stream_type == 0x82) && is_audio)
3292 demux[demux_id].STREAMpidsType[demux[demux_id].STREAMpidcount-1] = 0x03;
3293 stream_type = 0x03;
3295 else if(!vpid && stream_type == 0x80 && !is_audio)
3297 vpid = elementary_pid;
3300 else
3302 for(addentry = dvbapi_priority; addentry != NULL; addentry = addentry->next)
3304 if(addentry->type != 'a'
3305 || (addentry->ecmpid && pmtpid && addentry->ecmpid != pmtpid) // ecmpid is misused to hold pmtpid in case of A: rule
3306 || (addentry->ecmpid && !pmtpid && addentry->ecmpid != vpid) // some receivers dont forward pmtpid, use vpid instead
3307 || (addentry->srvid != demux[demux_id].program_number))
3308 { continue; }
3309 cs_log_dbg(D_DVBAPI, "Demuxer %d fake ecmpid %04X@%06X:%04x for unencrypted stream on srvid %04X", demux_id, addentry->mapcaid, addentry->mapprovid,
3310 addentry->mapecmpid, demux[demux_id].program_number);
3311 dvbapi_add_ecmpid(demux_id, addentry->mapcaid, addentry->mapecmpid, addentry->mapprovid, " (fake ecmpid)");
3312 break;
3317 if(!is_real_pmt)
3319 cs_log("Demuxer %d found %d ECMpids and %d STREAMpids in caPMT", demux_id, demux[demux_id].ECMpidcount, demux[demux_id].STREAMpidcount);
3321 getDemuxOptions(demux_id, buffer, &ca_mask, &demux_index, &adapter_index, &pmtpid);
3322 demux[demux_id].adapter_index = adapter_index;
3323 demux[demux_id].ca_mask = ca_mask;
3324 demux[demux_id].rdr = NULL;
3325 demux[demux_id].demux_index = demux_index;
3326 demux[demux_id].socket_fd = connfd;
3327 demux[demux_id].client_proto_version = client_proto_version;
3329 if(demux[demux_id].STREAMpidcount == 0) // encrypted PMT
3331 demux[demux_id].STREAMpids[demux[demux_id].STREAMpidcount] = pmtpid;
3332 demux[demux_id].STREAMpidsType[demux[demux_id].STREAMpidcount] = 0x01;
3333 demux[demux_id].STREAMpidcount++;
3334 vpid = pmtpid;
3337 else
3339 cs_log("Demuxer %d found %d ECMpids and %d STREAMpids in PMT", demux_id, demux[demux_id].ECMpidcount, demux[demux_id].STREAMpidcount);
3341 ca_mask = demux[demux_id].ca_mask;
3342 demux_index = demux[demux_id].demux_index;
3343 adapter_index = demux[demux_id].adapter_index;
3344 connfd = demux[demux_id].socket_fd;
3347 for(j = 0; j < demux[demux_id].ECMpidcount; j++)
3349 demux[demux_id].ECMpids[j].VPID = vpid; // register found vpid on all ecmpids of this demuxer
3352 char channame[CS_SERVICENAME_SIZE];
3353 get_servicename(dvbapi_client, demux[demux_id].program_number, demux[demux_id].ECMpidcount > 0 ? demux[demux_id].ECMpids[0].PROVID : 0 , demux[demux_id].ECMpidcount > 0 ? demux[demux_id].ECMpids[0].CAID : NO_CAID_VALUE, channame, sizeof(channame));
3354 cs_log("Demuxer %d serving srvid %04X (%s) on adapter %04X camask %04X index %04X pmtpid %04X", demux_id,
3355 demux[demux_id].program_number, channame, adapter_index, ca_mask, demux_index, pmtpid);
3357 demux[demux_id].stopdescramble = 0; // remove deletion mark!
3359 // remove from unassoc_fd when necessary
3360 if(!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX)
3361 for (j = 0; j < MAX_DEMUX; j++)
3362 if (unassoc_fd[j] == connfd)
3363 unassoc_fd[j] = 0;
3365 dvbapi_capmt_notify(&demux[demux_id]);
3367 struct s_dvbapi_priority *xtraentry;
3368 int32_t k, l, m, xtra_demux_id;
3370 for(xtraentry = dvbapi_priority; xtraentry != NULL; xtraentry = xtraentry->next)
3372 if(xtraentry->type != 'x') { continue; }
3374 for(j = 0; j <= demux[demux_id].ECMpidcount; ++j)
3376 if((xtraentry->caid && xtraentry->caid != demux[demux_id].ECMpids[j].CAID)
3377 || (xtraentry->provid && xtraentry->provid != demux[demux_id].ECMpids[j].PROVID)
3378 || (xtraentry->ecmpid && xtraentry->ecmpid != demux[demux_id].ECMpids[j].ECM_PID)
3379 || (xtraentry->srvid && xtraentry->srvid != demux[demux_id].program_number))
3380 { continue; }
3382 cs_log("Mapping ecmpid %04X@%06X:%04X:%04X to xtra demuxer/ca-devices", xtraentry->caid, xtraentry->provid, xtraentry->ecmpid, xtraentry->srvid);
3384 for(xtra_demux_id = 0; xtra_demux_id < MAX_DEMUX && demux[xtra_demux_id].program_number > 0; xtra_demux_id++)
3385 { ; }
3387 if(xtra_demux_id >= MAX_DEMUX)
3389 cs_log("Found no free demux device for xtra streams.");
3390 continue;
3392 // copy to new demuxer
3393 if(!is_real_pmt)
3395 getDemuxOptions(demux_id, buffer, &ca_mask, &demux_index, &adapter_index, &pmtpid);
3397 demux[xtra_demux_id].ECMpids[0] = demux[demux_id].ECMpids[j];
3398 demux[xtra_demux_id].ECMpidcount = 1;
3399 demux[xtra_demux_id].STREAMpidcount = 0;
3400 demux[xtra_demux_id].program_number = demux[demux_id].program_number;
3401 demux[xtra_demux_id].pmtpid = demux[demux_id].pmtpid;
3402 demux[xtra_demux_id].demux_index = demux_index;
3403 demux[xtra_demux_id].adapter_index = adapter_index;
3404 demux[xtra_demux_id].ca_mask = ca_mask;
3405 demux[xtra_demux_id].socket_fd = connfd;
3406 demux[xtra_demux_id].stopdescramble = 0; // remove deletion mark!
3407 demux[xtra_demux_id].rdr = NULL;
3408 demux[xtra_demux_id].curindex = -1;
3410 // add streams to xtra demux
3411 for(k = 0; k < demux[demux_id].STREAMpidcount; ++k)
3413 if(!demux[demux_id].ECMpids[j].streams || (demux[demux_id].ECMpids[j].streams & (1 << k)))
3415 demux[xtra_demux_id].ECMpids[0].streams |= (1 << demux[xtra_demux_id].STREAMpidcount);
3416 demux[xtra_demux_id].STREAMpids[demux[xtra_demux_id].STREAMpidcount] = demux[demux_id].STREAMpids[k];
3417 demux[xtra_demux_id].STREAMpidsType[demux[xtra_demux_id].STREAMpidcount] = demux[demux_id].STREAMpidsType[k];
3418 ++demux[xtra_demux_id].STREAMpidcount;
3420 // shift stream associations in normal demux because we will remove the stream entirely
3421 for(l = 0; l < demux[demux_id].ECMpidcount; ++l)
3423 for(m = k; m < demux[demux_id].STREAMpidcount - 1; ++m)
3425 if(demux[demux_id].ECMpids[l].streams & (1 << (m + 1)))
3427 demux[demux_id].ECMpids[l].streams |= (1 << m);
3429 else
3431 demux[demux_id].ECMpids[l].streams &= ~(1 << m);
3436 // remove stream association from normal demux device
3437 for(l = k; l < demux[demux_id].STREAMpidcount - 1; ++l)
3439 demux[demux_id].STREAMpids[l] = demux[demux_id].STREAMpids[l + 1];
3440 demux[demux_id].STREAMpidsType[l] = demux[demux_id].STREAMpidsType[l + 1];
3442 --demux[demux_id].STREAMpidcount;
3443 --k;
3447 // remove ecmpid from normal demuxer
3448 for(k = j; k < demux[demux_id].ECMpidcount; ++k)
3450 demux[demux_id].ECMpids[k] = demux[demux_id].ECMpids[k + 1];
3452 --demux[demux_id].ECMpidcount;
3453 --j;
3455 if(demux[xtra_demux_id].STREAMpidcount <= 0)
3457 cs_log("Found no streams for xtra demuxer. Not starting additional decoding on it.");
3458 demux[xtra_demux_id].program_number = 0;
3459 demux[xtra_demux_id].stopdescramble = 1;
3462 if(demux[demux_id].STREAMpidcount < 1)
3464 cs_log("Found no streams for normal demuxer. Not starting additional decoding on it.");
3469 demux[demux_id].sdt_filter = -1;
3471 if(cfg.dvbapi_au > 0 && demux[demux_id].EMMpidcount == 0) // only do emm setup if au enabled and not running!
3473 demux[demux_id].emm_filter = -1; // to register first run emmfilter start
3474 if(demux[demux_id].emmstart.time == 1) // irdeto fetch emm cat direct!
3476 cs_ftime(&demux[demux_id].emmstart); // trick to let emm fetching start after 30 seconds to speed up zapping
3477 dvbapi_start_filter(demux_id, demux[demux_id].pidindex, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM); //CAT
3479 else { cs_ftime(&demux[demux_id].emmstart); } // for all other caids delayed start!
3482 if(start_descrambling)
3484 for(j = 0; j < MAX_DEMUX; j++)
3486 if(demux[j].program_number == 0) { continue; }
3487 if(demux[j].socket_fd != connfd) { continue; } // skip demuxers belonging to other ca pmt connection
3488 if((demux[j].socket_fd == -1) && (pmtfile && strcmp(demux[j].pmt_file, pmtfile) != 0)) { continue; } // skip demuxers handled by other pmt files
3490 if(demux[j].running && demux_id == j) disable_unused_streampids(j); // disable all streampids not in use anymore
3492 if(demux[j].running == 0 && demux[j].ECMpidcount != 0 ) // only start demuxer if it wasnt running
3494 dvbapi_stop_all_emm_sdt_filtering(); // remove all unimportant filtering (there are images with limited amount of filters available!)
3495 cs_log_dbg(D_DVBAPI, "Demuxer %d/%d lets start descrambling (srvid = %04X fd = %d ecmpids = %d)", j, MAX_DEMUX,
3496 demux[j].program_number, connfd, demux[j].ECMpidcount);
3497 demux[j].running = 1; // mark channel as running
3498 openxcas_set_sid(demux[j].program_number);
3499 demux[j].decodingtries = -1;
3500 dvbapi_resort_ecmpids(j);
3501 dvbapi_try_next_caid(j, 0);
3502 cs_sleepms(1);
3504 else if(demux[j].ECMpidcount == 0) //fta do logging and part of ecmhandler since there will be no ecms asked!
3506 cs_log_dbg(D_DVBAPI, "Demuxer %d/%d no descrambling needed (srvid = %04X fd = %d ecmpids = %d)", j, MAX_DEMUX,
3507 demux[j].program_number, connfd, demux[j].ECMpidcount);
3508 demux[j].running = 0; // reset running flag
3509 demux[demux_id].pidindex = -1; // reset ecmpid used for descrambling
3510 dvbapi_stop_filter(j, TYPE_ECM);
3511 if(cfg.usrfileflag) { cs_statistics(dvbapi_client);} // add to user log previous channel + time on channel
3512 dvbapi_client->last_srvid = demux[demux_id].program_number; // set new channel srvid
3513 dvbapi_client->last_caid = NO_CAID_VALUE; // FTA channels have no caid!
3514 dvbapi_client->last_provid = NO_PROVID_VALUE; // FTA channels have no provid!
3515 dvbapi_client->lastswitch = dvbapi_client->last = time((time_t *)0); // reset idle-Time & last switch
3519 return demux_id;
3522 static uint32_t dvbapi_extract_sdt_string(char *buf, uint32_t buflen, uint8_t* source, uint32_t sourcelen)
3524 uint32_t i, j, offset = 0;
3525 int8_t iso_mode = -1;
3526 char *tmpbuf;
3527 const unsigned char *ptr_in;
3528 unsigned char *ptr_out;
3529 size_t in_bytes, out_bytes;
3531 if(sourcelen == 0)
3533 buf[0] = '\0';
3534 return 1;
3537 if(!cs_malloc(&tmpbuf, buflen))
3539 return 0;
3542 if((sourcelen + 1) > buflen)
3543 { sourcelen = buflen - 1; }
3545 if(sourcelen > 0 && source[0] < 0x20)
3547 //ISO-8859
3548 if(source[0] >= 0x01 && source[0] <= 0x0B && source[0] != 0x08)
3549 { offset = 1; iso_mode = 4+source[0]; }
3551 //ISO-8859
3552 else if(source[0] == 0x10 && source[1] == 0x00
3553 && source[2] >= 0x01 && source[2] <= 0x0F && source[2] != 0x0C)
3554 { offset = 3; iso_mode = source[2]; }
3556 //Unicode
3557 else if(source[0] == 0x11)
3558 { offset = 1; iso_mode = -2;}
3560 //missing: 0x12 Korean Character Set KSC5601-1987
3561 //missing: 0x13 Simplified Chinese Character Set GB-2312-1980
3562 //missing: 0x14 Big5 subset of ISO/IEC 10646-1 (Traditional Chinese)
3564 //Unicode as UTF-8
3565 else if(source[0] == 0x15)
3566 { offset = 1; iso_mode = -3;}
3568 //missing: 0x1F Described by encoding_type_id *standard not finished yet*
3570 //Reserved for future use
3571 else
3572 { NULLFREE(tmpbuf); return 0; }
3575 if(offset >= sourcelen)
3576 { NULLFREE(tmpbuf); return 0; }
3578 if(iso_mode >= -1)
3580 for(i=0, j=0; i<(sourcelen-offset); i++)
3582 if(((uint8_t)source[offset+i]) >= 0x80 && ((uint8_t)source[offset+i]) <= 0x9F)
3584 continue;
3587 tmpbuf[j] = source[offset+i];
3588 j++;
3590 tmpbuf[j] = '\0';
3593 ptr_in = (const unsigned char *)tmpbuf;
3594 in_bytes = strlen(tmpbuf);
3595 ptr_out = (unsigned char *)buf;
3596 out_bytes = buflen;
3598 #ifdef READ_SDT_CHARSETS
3599 if(iso_mode >= -1)
3601 memset(buf, 0, buflen);
3603 cs_log_dbg(D_DVBAPI, "sdt-info dbg: iso_mode: %d offset: %u", iso_mode, offset);
3604 cs_log_dump_dbg(D_DVBAPI, (uint8_t*)tmpbuf, in_bytes, "sdt-info dbg: raw string: ");
3606 if(iso_mode == -1)
3608 if(ISO6937toUTF8(&ptr_in, &in_bytes, &ptr_out, &out_bytes) == (size_t)(-1))
3610 cs_log_dbg(D_DVBAPI, "sdt-info error: ISO6937toUTF8 failed");
3611 NULLFREE(tmpbuf);
3612 return 0;
3615 else
3617 if(ISO8859toUTF8(iso_mode, &ptr_in, &in_bytes, &ptr_out, &out_bytes) == (size_t)(-1))
3619 cs_log_dbg(D_DVBAPI, "sdt-info error: ISO8859toUTF8 failed");
3620 NULLFREE(tmpbuf);
3621 return 0;
3625 #else
3626 if(iso_mode >= -1)
3628 cs_strncpy(buf, tmpbuf, buflen);
3629 cs_log_dbg(D_DVBAPI, "sdt-info warning: your build of oscam does not support iso-to-utf8 conversion, special chars may be corrupted!");
3631 #endif
3633 else if(iso_mode == -2)
3635 memset(buf, 0, buflen);
3637 cs_log_dbg(D_DVBAPI, "sdt-info dbg: iso_mode: %d offset: %u", iso_mode, offset);
3639 if(UnicodetoUTF8(&ptr_in, &in_bytes, &ptr_out, &out_bytes) == (size_t)(-1))
3641 cs_log_dbg(D_DVBAPI, "sdt-info error: UnicodetoUTF8 failed");
3642 NULLFREE(tmpbuf);
3643 return 0;
3647 else if(iso_mode == -3)
3649 memcpy(buf, source+offset, sourcelen-offset);
3650 buf[sourcelen-offset] = '\0';
3652 cs_log_dbg(D_DVBAPI, "sdt-info dbg: iso_mode: -3 offset: %u", offset);
3655 cs_log_dump_dbg(D_DVBAPI, (uint8_t*)buf, strlen(buf), "sdt-info dbg: encoded string: ");
3657 NULLFREE(tmpbuf);
3658 return 1;
3661 static void dvbapi_create_srvid_line(int32_t demux_id, char *buffer, uint32_t buflen)
3663 int32_t i, j;
3664 uint16_t caid_done[32], cur_caid;
3665 uint8_t caid_done_count = 0, skip_caid;
3666 int32_t pos = 0;
3668 if(demux[demux_id].ECMpidcount == 0)
3670 snprintf(buffer, buflen, "%04X@%06X", NO_CAID_VALUE, NO_PROVID_VALUE);
3671 return;
3674 for(i=0; i < demux[demux_id].ECMpidcount && i < 32; i++)
3676 skip_caid = 0;
3678 for(j=0; j < caid_done_count; j++)
3680 if(caid_done[j] == demux[demux_id].ECMpids[i].CAID)
3682 skip_caid = 1;
3683 break;
3687 if(skip_caid)
3689 continue;
3692 cur_caid = demux[demux_id].ECMpids[i].CAID;
3693 pos += snprintf(buffer+pos, buflen-pos, "%s%04X", caid_done_count > 0 ? "," : "", cur_caid == 0 ? NO_CAID_VALUE : cur_caid);
3695 for(j=i; j < demux[demux_id].ECMpidcount; j++)
3697 if(demux[demux_id].ECMpids[j].PROVID == 0)
3699 continue;
3702 if(cur_caid == demux[demux_id].ECMpids[j].CAID)
3704 pos += snprintf(buffer+pos, buflen-pos, "@%06X", demux[demux_id].ECMpids[j].PROVID);
3708 caid_done[caid_done_count] = demux[demux_id].ECMpids[i].CAID;
3709 caid_done_count++;
3713 static const char *dvbapi_get_service_type(uint8_t service_type_id)
3715 switch(service_type_id)
3717 case 0x01:
3718 case 0x11:
3719 default:
3720 return "TV";
3722 case 0x02:
3723 case 0x07:
3724 case 0x0A:
3725 return "Radio";
3727 case 0x03:
3728 return "Teletext";
3730 case 0x0C:
3731 return "Data";
3735 static void dvbapi_parse_sdt(int32_t demux_id, unsigned char *buffer, uint32_t length)
3737 uint8_t tag, data_length = 0, provider_name_length, service_name_length, service_type;
3738 uint16_t service_id, descriptor_length, dpos;
3739 int32_t provid, caid;
3740 uint32_t section_length, pos;
3741 int32_t pidindex;
3742 char provider_name[64], service_name[64], tmp[256], srvid_line[1024];
3743 const char *type;
3744 FILE *fpsave = NULL;
3745 int8_t did_save_srvid = 0;
3747 cs_log_dump_dbg(D_DVBAPI, buffer, length, "sdt-info dbg: sdt data: ");
3749 if(length < 3)
3750 { return; }
3752 if(buffer[0] != 0x42)
3753 { return; }
3755 section_length = b2i(2, buffer + 1) &0xFFF;
3757 if(section_length+3 != length)
3758 { return; }
3760 for(pos = 11; pos+5 < length; pos += descriptor_length)
3762 service_id = b2i(2, buffer + pos);
3763 descriptor_length = b2i(2, buffer + pos + 3) &0xFFF;
3765 if((pos+5+descriptor_length) >= length)
3766 { return; }
3768 pos += 5;
3770 if(service_id != demux[demux_id].program_number)
3771 { continue; }
3773 for(dpos = 0; dpos+1 < descriptor_length; dpos += (2 + data_length))
3775 tag = buffer[pos+dpos];
3776 data_length = buffer[pos+dpos+1];
3778 if(dpos+1+data_length >= descriptor_length)
3779 { break; }
3781 if(tag != 0x48)
3782 { continue; }
3784 if(dpos+3 >= descriptor_length)
3785 { break; }
3787 service_type = buffer[pos+dpos+2];
3789 provider_name_length = buffer[pos+dpos+3];
3790 if((dpos+4+provider_name_length+1) > descriptor_length)
3791 { break; }
3793 service_name_length = buffer[pos+dpos+4+provider_name_length];
3794 if((dpos+4+provider_name_length+1+service_name_length) > descriptor_length)
3795 { break; }
3797 pidindex = demux[demux_id].pidindex;
3799 if (pidindex !=-1)
3801 provid = demux[demux_id].ECMpids[pidindex].PROVID;
3802 caid = demux[demux_id].ECMpids[pidindex].CAID;
3804 else
3806 if(demux[demux_id].ECMpidcount == 0 || demux[demux_id].ECMpids[0].CAID == 0)
3808 caid = NO_CAID_VALUE;
3809 provid = NO_PROVID_VALUE;
3811 else
3813 caid = demux[demux_id].ECMpids[0].CAID;
3814 provid = demux[demux_id].ECMpids[0].PROVID;
3818 if(!dvbapi_extract_sdt_string(provider_name, sizeof(provider_name), buffer+pos+dpos+4, provider_name_length))
3819 { break; }
3821 if(!dvbapi_extract_sdt_string(service_name, sizeof(service_name), buffer+pos+dpos+4+provider_name_length+1, service_name_length))
3822 { break; }
3824 cs_log("sdt-info (provider: %s - channel: %s)", provider_name, service_name);
3826 dvbapi_stop_filter(demux_id, TYPE_SDT);
3828 if(strlen(provider_name) && caid != NO_CAID_VALUE)
3830 get_providername_or_null(provid, caid, tmp, sizeof(tmp));
3832 if(tmp[0] == '\0')
3834 get_config_filename(tmp, sizeof(tmp), "oscam.provid");
3836 if((fpsave = fopen(tmp, "a")))
3838 fprintf(fpsave, "\n%04X@%06X|%s|", caid, provid, provider_name);
3839 fclose(fpsave);
3841 init_provid();
3846 if(strlen(service_name))
3848 get_servicename_or_null(cur_client(), service_id, provid, caid, tmp, sizeof(tmp));
3850 if(tmp[0] == '\0')
3852 type = dvbapi_get_service_type(service_type);
3854 get_config_filename(tmp, sizeof(tmp), "oscam.srvid2");
3856 if(!access(tmp, F_OK) && (fpsave = fopen(tmp, "a")))
3858 if((caid != NO_CAID_VALUE) || (cfg.dvbapi_read_sdt > 1))
3860 dvbapi_create_srvid_line(demux_id, srvid_line, sizeof(srvid_line));
3862 if(cfg.dvbapi_write_sdt_prov)
3863 { fprintf(fpsave, "\n%04X:%s|%s|%s||%s", service_id, srvid_line, service_name, type, provider_name); }
3864 else
3865 { fprintf(fpsave, "\n%04X:%s|%s|%s", service_id, srvid_line, service_name, type); }
3867 did_save_srvid = 1;
3870 else
3872 get_config_filename(tmp, sizeof(tmp), "oscam.srvid");
3874 if((fpsave = fopen(tmp, "a")))
3876 if((caid != NO_CAID_VALUE) || (cfg.dvbapi_read_sdt > 1))
3878 dvbapi_create_srvid_line(demux_id, srvid_line, sizeof(srvid_line));
3880 if(cfg.dvbapi_write_sdt_prov)
3881 { fprintf(fpsave, "\n%s:%04X|%s|%s|%s", srvid_line, service_id, provider_name, service_name, type); }
3883 else
3884 { fprintf(fpsave, "\n%s:%04X||%s|%s", srvid_line, service_id, service_name, type); }
3886 did_save_srvid = 1;
3891 if(fpsave)
3892 { fclose(fpsave); }
3894 if(did_save_srvid)
3895 { init_srvid(); }
3899 return;
3904 static void dvbapi_parse_pat(int32_t demux_id, unsigned char *buffer, uint32_t length)
3906 uint16_t srvid;
3907 uint32_t i;
3909 dvbapi_stop_filter(demux_id, TYPE_PAT);
3911 for(i=8; i+7<length; i+=4)
3913 srvid = b2i(2, buffer+i);
3915 if(srvid == 0)
3916 { continue; }
3918 if(demux[demux_id].program_number == srvid)
3920 dvbapi_start_pmt_filter(demux_id, b2i(2, buffer+i+2) & 0x1FFF);
3921 break;
3926 int32_t dvbapi_init_listenfd(void)
3928 int32_t clilen, listenfd;
3929 struct sockaddr_un servaddr;
3931 memset(&servaddr, 0, sizeof(struct sockaddr_un));
3932 servaddr.sun_family = AF_UNIX;
3933 cs_strncpy(servaddr.sun_path, devices[selected_box].cam_socket_path, sizeof(servaddr.sun_path));
3934 clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
3936 if((unlink(devices[selected_box].cam_socket_path) < 0) && (errno != ENOENT))
3937 { return 0; }
3938 if((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
3939 { return 0; }
3940 if(bind(listenfd, (struct sockaddr *)&servaddr, clilen) < 0)
3941 { return 0; }
3942 if(listen(listenfd, 5) < 0)
3943 { return 0; }
3945 // change the access right on the camd.socket
3946 // this will allow oscam to run as root if needed
3947 // and still allow non root client to connect to the socket
3948 chmod(devices[selected_box].cam_socket_path, S_IRWXU | S_IRWXG | S_IRWXO);
3950 return listenfd;
3953 int32_t dvbapi_net_init_listenfd(void)
3955 int32_t listenfd;
3956 struct SOCKADDR servaddr;
3958 memset(&servaddr, 0, sizeof(servaddr));
3959 SIN_GET_FAMILY(servaddr) = DEFAULT_AF;
3960 SIN_GET_ADDR(servaddr) = ADDR_ANY;
3961 SIN_GET_PORT(servaddr) = htons((uint16_t)cfg.dvbapi_listenport);
3963 if((listenfd = socket(DEFAULT_AF, SOCK_STREAM, 0)) < 0)
3964 { return 0; }
3966 int32_t opt = 0;
3967 #ifdef IPV6SUPPORT
3969 // azbox toolchain do not have this define
3970 #ifndef IPV6_V6ONLY
3971 #define IPV6_V6ONLY 26
3972 #endif
3974 // set the server socket option to listen on IPv4 and IPv6 simultaneously
3975 setsockopt(listenfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&opt, sizeof(opt));
3976 #endif
3978 opt = 1;
3979 setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt));
3980 set_so_reuseport(listenfd);
3982 if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
3983 { return 0; }
3984 if(listen(listenfd, 5) < 0)
3985 { return 0; }
3987 return listenfd;
3990 static pthread_mutex_t event_handler_lock;
3992 void event_handler(int32_t UNUSED(signal))
3994 struct stat pmt_info;
3995 char dest[1024];
3996 DIR *dirp;
3997 struct dirent entry, *dp = NULL;
3998 int32_t i, pmt_fd;
3999 uchar mbuf[2048]; // dirty fix: larger buffer needed for CA PMT mode 6 with many parallel channels to decode
4000 if(dvbapi_client != cur_client()) { return; }
4002 SAFE_MUTEX_LOCK(&event_handler_lock);
4004 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX || cfg.dvbapi_boxtype == BOXTYPE_SAMYGO)
4005 { pausecam = 0; }
4006 else
4008 int32_t standby_fd = open(STANDBY_FILE, O_RDONLY);
4009 pausecam = (standby_fd > 0) ? 1 : 0;
4010 if(standby_fd > 0)
4012 int32_t ret = close(standby_fd);
4013 if(ret < 0) { cs_log("ERROR: Could not close standby fd (errno=%d %s)", errno, strerror(errno)); }
4017 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX || cfg.dvbapi_pmtmode == 1)
4019 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4020 return;
4023 for(i = 0; i < MAX_DEMUX; i++)
4025 if(demux[i].pmt_file[0] != 0)
4027 snprintf(dest, sizeof(dest), "%s%s", TMPDIR, demux[i].pmt_file);
4028 pmt_fd = open(dest, O_RDONLY);
4029 if(pmt_fd > 0)
4031 if(fstat(pmt_fd, &pmt_info) != 0)
4033 int32_t ret = close(pmt_fd);
4034 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4035 continue;
4038 if((time_t)pmt_info.st_mtime != demux[i].pmt_time)
4040 dvbapi_stop_descrambling(i);
4043 int32_t ret = close(pmt_fd);
4044 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4045 continue;
4047 else
4049 cs_log("Demuxer %d Unable to open PMT file %s -> stop descrambling!", i, dest);
4050 dvbapi_stop_descrambling(i);
4055 if(disable_pmt_files)
4057 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4058 return;
4061 dirp = opendir(TMPDIR);
4062 if(!dirp)
4064 cs_log_dbg(D_DVBAPI, "opendir failed (errno=%d %s)", errno, strerror(errno));
4065 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4066 return;
4069 while(!cs_readdir_r(dirp, &entry, &dp))
4071 if(!dp) { break; }
4073 if(strlen(dp->d_name) < 7)
4074 { continue; }
4075 if(strncmp(dp->d_name, "pmt", 3) != 0 || strncmp(dp->d_name + strlen(dp->d_name) - 4, ".tmp", 4) != 0)
4076 { continue; }
4077 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
4078 struct s_dvbapi_priority *p;
4079 for(p = dvbapi_priority; p != NULL; p = p->next) // stapi: check if there is a device connected to this pmt file!
4081 if(p->type != 's') { continue; } // stapi rule?
4082 if(strcmp(dp->d_name, p->pmtfile) != 0) { continue; } // same file?
4083 break; // found match!
4085 if(p == NULL)
4087 cs_log_dbg(D_DVBAPI, "No matching S: line in oscam.dvbapi for pmtfile %s -> skip!", dp->d_name);
4088 continue;
4090 #endif
4091 snprintf(dest, sizeof(dest), "%s%s", TMPDIR, dp->d_name);
4092 pmt_fd = open(dest, O_RDONLY);
4093 if(pmt_fd < 0)
4094 { continue; }
4096 if(fstat(pmt_fd, &pmt_info) != 0)
4098 int32_t ret = close(pmt_fd);
4099 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4100 continue;
4103 int32_t found = 0;
4104 for(i = 0; i < MAX_DEMUX; i++)
4106 if(strcmp(demux[i].pmt_file, dp->d_name) == 0)
4108 if((time_t)pmt_info.st_mtime == demux[i].pmt_time)
4110 found = 1;
4111 break;
4115 if(found)
4117 int32_t ret = close(pmt_fd);
4118 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4119 continue;
4122 cs_log_dbg(D_DVBAPI, "found pmt file %s", dest);
4123 cs_sleepms(100);
4125 uint32_t len = read(pmt_fd, mbuf, sizeof(mbuf));
4126 int32_t ret = close(pmt_fd);
4127 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4129 if(len < 1)
4131 cs_log_dbg(D_DVBAPI, "pmt file %s have invalid len!", dest);
4132 continue;
4135 int32_t pmt_id;
4137 #ifdef QBOXHD
4138 uint32_t j1, j2;
4139 // QboxHD pmt.tmp is the full capmt written as a string of hex values
4140 // pmt.tmp must be longer than 3 bytes (6 hex chars) and even length
4141 if((len < 6) || ((len % 2) != 0) || ((len / 2) > sizeof(dest)))
4143 cs_log_dbg(D_DVBAPI, "error parsing QboxHD pmt.tmp, incorrect length");
4144 continue;
4147 for(j2 = 0, j1 = 0; j2 < len; j2 += 2, j1++)
4149 unsigned int tmp;
4150 if(sscanf((char *)mbuf + j2, "%02X", &tmp) != 1)
4152 cs_log_dbg(D_DVBAPI, "error parsing QboxHD pmt.tmp, data not valid in position %d", j2);
4153 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4154 return;
4156 else
4158 memcpy(dest + j1, &tmp, 4);
4162 cs_log_dump_dbg(D_DVBAPI, (unsigned char *)dest, len / 2, "QboxHD pmt.tmp:");
4163 pmt_id = dvbapi_parse_capmt((unsigned char *)dest + 4, (len / 2) - 4, -1, dp->d_name, 0, 0, 0);
4164 #else
4165 if(len > sizeof(dest))
4167 cs_log_dbg(D_DVBAPI, "event_handler() dest buffer is to small for pmt data!");
4168 continue;
4170 if(len < 16)
4172 cs_log_dbg(D_DVBAPI, "event_handler() received pmt is too small! (%d < 16 bytes!)", len);
4173 continue;
4175 cs_log_dump_dbg(D_DVBAPI, mbuf, len, "pmt:");
4177 dest[0] = 0x03;
4178 dest[1] = mbuf[3];
4179 dest[2] = mbuf[4];
4180 uint32_t pmt_program_length = b2i(2, mbuf + 10)&0xFFF;
4181 i2b_buf(2, pmt_program_length + 1, (uchar *) dest + 4);
4182 dest[6] = 0;
4184 memcpy(dest + 7, mbuf + 12, len - 12 - 4);
4186 pmt_id = dvbapi_parse_capmt((uchar *)dest, 7 + len - 12 - 4, -1, dp->d_name, 0, 0, 0);
4187 #endif
4189 if(pmt_id >= 0)
4191 cs_strncpy(demux[pmt_id].pmt_file, dp->d_name, sizeof(demux[pmt_id].pmt_file));
4192 demux[pmt_id].pmt_time = (time_t)pmt_info.st_mtime;
4195 if(cfg.dvbapi_pmtmode == 3)
4197 disable_pmt_files = 1;
4198 break;
4201 closedir(dirp);
4202 SAFE_MUTEX_UNLOCK(&event_handler_lock);
4205 void *dvbapi_event_thread(void *cli)
4207 struct s_client *client = (struct s_client *) cli;
4208 SAFE_SETSPECIFIC(getclient, client);
4209 set_thread_name(__func__);
4210 while(!exit_oscam)
4212 cs_sleepms(750);
4213 event_handler(0);
4216 return NULL;
4219 void dvbapi_process_input(int32_t demux_id, int32_t filter_num, uchar *buffer, int32_t len)
4221 struct s_ecmpids *curpid = NULL;
4222 int32_t pid = demux[demux_id].demux_fd[filter_num].pidindex;
4223 uint16_t filtertype = demux[demux_id].demux_fd[filter_num].type;
4224 uint32_t sctlen = SCT_LEN(buffer);
4226 if((uint) len < sctlen) // invalid CAT length
4228 cs_log_dbg(D_DVBAPI, "Received filterdata with total length 0x%03X but section length is 0x%03X -> invalid length!", len, sctlen);
4229 return;
4232 if(demux_id < 0 || demux_id >= MAX_DEMUX)
4234 cs_log("dvbapi_process_input(): error - received invalid demux_id (%d)", demux_id);
4235 return;
4238 if(filter_num < 0 || filter_num >= MAX_FILTER)
4240 cs_log("dvbapi_process_input(): error - received invalid filter_num (%d)", filter_num);
4241 return;
4244 if(pid != -1 && filtertype == TYPE_ECM)
4246 curpid = &demux[demux_id].ECMpids[pid];
4249 int32_t filt_match = filtermatch(buffer, filter_num, demux_id, sctlen); // acts on all filters (sdt/emm/ecm)
4250 if(!filt_match)
4252 cs_log_dbg(D_DVBAPI,"Demuxer %d receiver returned data that was not matching to the filter -> delivered filter data discarded!", demux_id);
4253 return;
4256 if(curpid && curpid->tries <= 0xF0 && filtertype == TYPE_ECM)
4258 curpid->irdeto_maxindex = 0;
4259 curpid->irdeto_curindex = 0xFE;
4260 curpid->tries = 0xFE; // reset timeout retry flag
4261 curpid->irdeto_cycle = 0xFE; // reset irdetocycle
4262 curpid->table = 0;
4263 curpid->checked = 4; // flag ecmpid as checked
4264 curpid->status = -1; // flag ecmpid as unusable
4265 if(pid == demux[demux_id].pidindex)
4267 demux[demux_id].pidindex = -1; // current pid delivered problems so this pid isnt being used to descramble any longer-> clear pidindex
4268 dvbapi_edit_channel_cache(demux_id, pid, 0); // remove this pid from channelcache since we had no founds on any ecmpid!
4270 dvbapi_stop_filternum(demux_id, filter_num); // stop this ecm filter!
4271 return;
4274 if(filtertype == TYPE_ECM)
4276 uint32_t chid = 0x10000;
4277 ECM_REQUEST *er;
4279 if(len != 0) // len = 0 receiver encountered an internal bufferoverflow!
4281 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched ECM data (ecmlength = 0x%03X):", demux_id, filter_num + 1, sctlen);
4283 if(sctlen > MAX_ECM_SIZE) // ecm too long to handle!
4285 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);
4286 if(curpid)
4288 curpid->tries-=0x0E;
4290 return;
4293 if(!(buffer[0] == 0x80 || buffer[0] == 0x81))
4295 cs_log_dbg(D_DVBAPI, "Received an ECM with invalid ecmtable ID %02X -> ignoring!", buffer[0]);
4296 if(curpid)
4298 curpid->tries--;
4300 return;
4303 if(curpid->table == buffer[0] && !caid_is_irdeto(curpid->CAID)) // wait for odd / even ecm change (only not for irdeto!)
4306 if(!(er = get_ecmtask()))
4308 return;
4311 er->srvid = demux[demux_id].program_number;
4313 #ifdef WITH_STAPI5
4314 cs_strncpy(er->dev_name, dev_list[demux[demux_id].dev_index].name, sizeof(dev_list[demux[demux_id].dev_index].name));
4315 #endif
4317 er->tsid = demux[demux_id].tsid;
4318 er->onid = demux[demux_id].onid;
4319 er->pmtpid = demux[demux_id].pmtpid;
4320 er->ens = demux[demux_id].enigma_namespace;
4322 er->caid = curpid->CAID;
4323 er->pid = curpid->ECM_PID;
4324 er->prid = curpid->PROVID;
4325 er->vpid = curpid->VPID;
4326 er->ecmlen = sctlen;
4327 memcpy(er->ecm, buffer, er->ecmlen);
4328 chid = get_subid(er); // fetch chid or fake chid
4329 er->chid = chid;
4330 dvbapi_set_section_filter(demux_id, er, filter_num);
4331 NULLFREE(er);
4332 return;
4335 if(caid_is_irdeto(curpid->CAID))
4337 // 80 70 39 53 04 05 00 88
4338 // 81 70 41 41 01 06 00 13 00 06 80 38 1F 52 93 D2
4339 //if (buffer[5]>20) return;
4340 if(curpid->irdeto_maxindex != buffer[5]) //6, register max irdeto index
4342 cs_log_dbg(D_DVBAPI, "Found %d IRDETO ECM CHIDs", buffer[5] + 1);
4343 curpid->irdeto_maxindex = buffer[5]; // numchids = 7 (0..6)
4348 if(!(er = get_ecmtask()))
4350 return;
4353 er->srvid = demux[demux_id].program_number;
4355 #ifdef WITH_STAPI5
4356 cs_strncpy(er->dev_name, dev_list[demux[demux_id].dev_index].name, sizeof(dev_list[demux[demux_id].dev_index].name));
4357 #endif
4359 er->tsid = demux[demux_id].tsid;
4360 er->onid = demux[demux_id].onid;
4361 er->pmtpid = demux[demux_id].pmtpid;
4362 er->ens = demux[demux_id].enigma_namespace;
4364 er->caid = curpid->CAID;
4365 er->pid = curpid->ECM_PID;
4366 er->prid = curpid->PROVID;
4367 er->vpid = curpid->VPID;
4368 er->ecmlen = sctlen;
4369 memcpy(er->ecm, buffer, er->ecmlen);
4371 chid = get_subid(er); // fetch chid or fake chid
4372 uint32_t fixedprovid = chk_provid(er->ecm, er->caid);
4373 if(fixedprovid && fixedprovid != er->prid)
4375 cs_log_dbg(D_DVBAPI, "Fixing provid ecmpid %d from %06X -> %06X", pid, curpid->PROVID, fixedprovid);
4376 curpid->PROVID = fixedprovid;
4377 if(!USE_OPENXCAS)
4379 cs_log_dbg(D_DVBAPI, "Fixing provid filter %d from %06X -> %06X", filter_num+1, demux[demux_id].demux_fd[filter_num].provid, fixedprovid);
4380 demux[demux_id].demux_fd[filter_num].provid = fixedprovid;
4382 cs_log_dbg(D_DVBAPI, "Fixing provid ecmrequest from %06X -> %06X", er->prid, fixedprovid);
4383 er->prid = fixedprovid;
4385 er->chid = chid;
4387 if(len == 0) // only used on receiver internal bufferoverflow to get quickly fresh ecm filterdata otherwise freezing!
4389 curpid->table = 0;
4390 dvbapi_set_section_filter(demux_id, er, filter_num);
4391 NULLFREE(er);
4392 return;
4395 if(caid_is_irdeto(curpid->CAID))
4398 if(curpid->irdeto_curindex != buffer[4]) // old style wrong irdeto index
4400 if(curpid->irdeto_curindex == 0xFE) // check if this ecmfilter just started up
4402 curpid->irdeto_curindex = buffer[4]; // on startup set the current index to the irdeto index of the ecm
4404 else // we are already running and not interested in this ecm
4406 if(curpid->table != buffer[0]) curpid->table = 0; // fix for receivers not supporting section filtering
4407 dvbapi_set_section_filter(demux_id, er, filter_num); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4408 NULLFREE(er);
4409 return;
4412 else //fix for receivers not supporting section filtering
4414 if(curpid->table == buffer[0]){
4415 NULLFREE(er);
4416 return;
4419 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);
4421 else
4423 cs_log_dbg(D_DVBAPI, "Demuxer %d ECMTYPE %02X CAID %04X PROVID %06X ECMPID %04X FAKECHID %04X (unique part in ecm)",
4424 demux_id, er->ecm[0], er->caid, er->prid, er->pid, er->chid);
4427 // check for matching chid (unique ecm part in case of non-irdeto cas) + added fix for seca2 monthly changing fakechid
4428 if((curpid->CHID < 0x10000) && !((chid == curpid->CHID) || ((curpid->CAID >> 8 == 0x01) && (chid&0xF0FF) == (curpid->CHID&0xF0FF)) ) )
4430 if(caid_is_irdeto(curpid->CAID))
4433 if((curpid->irdeto_cycle < 0xFE) && (curpid->irdeto_cycle == curpid->irdeto_curindex)) // if same: we cycled all indexes but no luck!
4435 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match(demux_id, pid, 'p');
4436 if(!forceentry || !forceentry->force) // forced pid? keep trying the forced ecmpid, no force kill ecm filter
4438 if(curpid->checked == 2) { curpid->checked = 4; }
4439 if(curpid->checked == 1)
4441 curpid->checked = 2;
4442 curpid->CHID = 0x10000;
4444 dvbapi_stop_filternum(demux_id, filter_num); // stop this ecm filter!
4445 NULLFREE(er);
4446 return;
4450 curpid->irdeto_curindex++; // set check on next index
4451 if(curpid->irdeto_cycle == 0xFE) curpid->irdeto_cycle = buffer[4]; // on startup set to current irdeto index
4452 if(curpid->irdeto_curindex > curpid->irdeto_maxindex) { curpid->irdeto_curindex = 0; } // check if we reached max irdeto index, if so reset to 0
4454 curpid->table = 0;
4455 dvbapi_set_section_filter(demux_id, er, filter_num); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4456 NULLFREE(er);
4457 return;
4459 else // all nonirdeto cas systems
4461 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match(demux_id, pid, 'p');
4462 curpid->table = 0;
4463 dvbapi_set_section_filter(demux_id, er, filter_num); // set ecm filter to odd + even since this ecm doesnt match with current irdeto index
4464 if(forceentry && forceentry->force)
4466 NULLFREE(er);
4467 return; // forced pid? keep trying the forced ecmpid!
4469 if(curpid->checked == 2) { curpid->checked = 4; }
4470 if(curpid->checked == 1)
4472 curpid->checked = 2;
4473 curpid->CHID = 0x10000;
4475 dvbapi_stop_filternum(demux_id, filter_num); // stop this ecm filter!
4476 NULLFREE(er);
4477 return;
4481 struct s_dvbapi_priority *p;
4483 for(p = dvbapi_priority; p != NULL; p = p->next)
4485 if(p->type != 'l'
4486 || (p->caid && p->caid != curpid->CAID)
4487 || (p->provid && p->provid != curpid->PROVID)
4488 || (p->ecmpid && p->ecmpid != curpid->ECM_PID)
4489 || (p->srvid && p->srvid != demux[demux_id].program_number))
4490 { continue; }
4492 if((uint)p->delay == sctlen && p->force < 6)
4494 p->force++;
4495 NULLFREE(er);
4496 return;
4498 if(p->force >= 6)
4499 { p->force = 0; }
4502 if(!curpid->PROVID)
4503 { curpid->PROVID = chk_provid(buffer, curpid->CAID); }
4505 if(caid_is_irdeto(curpid->CAID)) // irdeto: wait for the correct index
4507 if(buffer[4] != curpid->irdeto_curindex)
4509 curpid->table = 0;
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 // we have an ecm with the correct irdeto index (or fakechid)
4516 for(p = dvbapi_priority; p != NULL ; p = p->next) // check for ignore!
4518 if((p->type != 'i')
4519 || (p->caid && p->caid != curpid->CAID)
4520 || (p->provid && p->provid != curpid->PROVID)
4521 || (p->ecmpid && p->ecmpid != curpid->ECM_PID)
4522 || (p->pidx && p->pidx-1 != pid)
4523 || (p->srvid && p->srvid != demux[demux_id].program_number))
4524 { continue; }
4526 if(p->type == 'i' && (p->chid < 0x10000 && p->chid == chid)) // found a ignore chid match with current ecm -> ignoring this irdeto index
4528 curpid->irdeto_curindex++;
4529 if(curpid->irdeto_cycle == 0xFE) curpid->irdeto_cycle = buffer[4]; // on startup set to current irdeto index
4530 if(curpid->irdeto_curindex > curpid->irdeto_maxindex) // check if curindex is over the max
4532 curpid->irdeto_curindex = 0;
4534 curpid->table = 0;
4535 if(caid_is_irdeto(curpid->CAID) && (curpid->irdeto_cycle != curpid->irdeto_curindex)) // irdeto: wait for the correct index + check if we cycled all
4537 dvbapi_set_section_filter(demux_id, er, filter_num); // set ecm filter to odd + even since this chid has to be ignored!
4539 else // this fakechid has to be ignored, kill this 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); // stop this ecm filter!
4549 NULLFREE(er);
4550 return;
4554 if(er) curpid->table = er->ecm[0];
4555 request_cw(dvbapi_client, er, demux_id, 1); // register this ecm for delayed ecm response check
4556 return; // end of ecm filterhandling!
4559 if(filtertype == TYPE_EMM)
4561 if(len != 0) // len = 0 receiver encountered an internal bufferoverflow!
4563 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched EMM data (emmlength = 0x%03X):", demux_id, filter_num + 1, sctlen);
4565 if(sctlen > MAX_EMM_SIZE) // emm too long to handle!
4567 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);
4568 return;
4571 else
4573 return; // just skip on internal bufferoverflow
4577 if(demux[demux_id].demux_fd[filter_num].pid == 0x01) // CAT
4579 cs_log_dbg(D_DVBAPI, "receiving cat");
4580 dvbapi_parse_cat(demux_id, buffer, sctlen);
4582 dvbapi_stop_filternum(demux_id, filter_num);
4583 return;
4585 dvbapi_process_emm(demux_id, filter_num, buffer, sctlen);
4588 if(filtertype == TYPE_SDT)
4590 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched SDT data (length = 0x%03X):", demux_id, filter_num + 1, sctlen);
4591 dvbapi_parse_sdt(demux_id, buffer, sctlen);
4594 if(filtertype == TYPE_PAT)
4596 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched PAT data (length = 0x%03X):", demux_id, filter_num + 1, sctlen);
4597 dvbapi_parse_pat(demux_id, buffer, sctlen);
4600 if(filtertype == TYPE_PMT)
4602 cs_log_dump_dbg(D_DVBAPI, buffer, sctlen, "Demuxer %d Filter %d fetched CAPMT data (length = 0x%03X):", demux_id, filter_num + 1, sctlen);
4603 dvbapi_parse_capmt(buffer, sctlen, demux[demux_id].socket_fd, demux[demux_id].pmt_file, 1, demux_id, demux[demux_id].client_proto_version);
4607 static int32_t dvbapi_recv(int32_t connfd, uchar* mbuf, size_t rlen)
4609 ssize_t len = cs_recv(connfd, mbuf, rlen, MSG_DONTWAIT);
4611 if((len == -1 && (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK)) || (len == 0))
4613 return -1;
4616 if(len == -1)
4618 return 0;
4621 return len;
4624 static uint16_t dvbapi_get_nbof_missing_header_bytes(uchar* mbuf, uint16_t mbuf_len)
4626 if(mbuf_len < 4)
4628 return 4 - mbuf_len;
4631 uint32_t opcode = b2i(4, mbuf); //get the client opcode (4 bytes)
4633 //detect the opcode, its size (chunksize) and its internal data size (data_len)
4634 if((opcode & 0xFFFFF000) == DVBAPI_AOT_CA) // min 4+size bytes
4636 if(mbuf[3] & 0x80)
4638 uint32_t size = mbuf[3] & 0x7F;
4640 if(mbuf_len < (4+size))
4642 return (4+size) - mbuf_len;
4645 return 0;
4647 else switch (opcode)
4649 case DVBAPI_FILTER_DATA: // min 9 bytes
4651 if(mbuf_len < 9)
4653 return 9 - mbuf_len;
4655 return 0;
4657 case DVBAPI_CLIENT_INFO: // min 7 bytes
4659 if(mbuf_len < 7)
4661 return 7 - mbuf_len;
4663 return 0;
4665 default:
4667 return 0;
4672 static void dvbapi_get_packet_size(uchar* mbuf, uint16_t mbuf_len, uint16_t* chunksize, uint16_t *data_len)
4674 //chunksize: size of complete chunk in the buffer (an opcode with the data)
4675 //data_len: variable for internal data length (eg. for the filter data size, PMT len)
4677 (*chunksize) = 0;
4678 (*data_len) = 0;
4680 if(mbuf_len < 4)
4682 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short", mbuf_len);
4683 (*chunksize) = 1;
4684 (*data_len) = 1;
4685 return;
4688 uint32_t opcode = b2i(4, mbuf); //get the client opcode (4 bytes)
4690 //detect the opcode, its size (chunksize) and its internal data size (data_len)
4691 if((opcode & 0xFFFFF000) == DVBAPI_AOT_CA) // min 4+size bytes
4693 // parse packet size (ASN.1)
4694 uint32_t size = 0;
4696 if(mbuf[3] & 0x80)
4698 uint32_t tmp_data_len = 0;
4700 size = mbuf[3] & 0x7F;
4702 if(3 + size < mbuf_len)
4704 uint32_t k;
4705 for (k = 0; k < size; k++)
4707 tmp_data_len = (tmp_data_len << 8) | mbuf[4 + k];
4710 else
4712 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short for opcode %08X", mbuf_len, opcode);
4713 (*chunksize) = 1;
4714 (*data_len) = 1;
4715 return;
4718 if(tmp_data_len > 0xFFFF)
4720 cs_log("Socket command too big: %d bytes", tmp_data_len);
4721 (*data_len) = 0xFFFF - 4 - size;
4723 else
4725 (*data_len) = tmp_data_len;
4728 else
4730 (*data_len) = mbuf[3] & 0x7F;
4733 (*chunksize) = 4 + size + (*data_len);
4735 cs_log_dbg(D_DVBAPI, "Got packet with opcode %08X and size %" PRIu16, opcode, (*chunksize));
4737 else switch (opcode)
4739 case DVBAPI_FILTER_DATA: // min 9 bytes
4741 if(mbuf_len < 9)
4743 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short for DVBAPI_FILTER_DATA", mbuf_len);
4744 (*chunksize) = 1;
4745 (*data_len) = 1;
4746 return;
4749 (*data_len) = b2i(2, mbuf + 7) & 0x0FFF;
4750 (*chunksize) = 6 + 3 + (*data_len);
4752 cs_log_dbg(D_DVBAPI, "Got DVBAPI_FILTER_DATA packet with size %" PRIu16, (*chunksize));
4753 break;
4755 case DVBAPI_CLIENT_INFO: // min 7 bytes
4757 if(mbuf_len < 7)
4759 cs_log("dvbapi_get_packet_size(): error - buffer length (%" PRIu16 ") too short for DVBAPI_CLIENT_INFO", mbuf_len);
4760 (*chunksize) = 1;
4761 (*data_len) = 1;
4762 return;
4765 (*data_len) = mbuf[6];
4766 (*chunksize) = 6 + 1 + (*data_len);
4768 cs_log_dbg(D_DVBAPI, "Got DVBAPI_CLIENT_INFO packet with size %" PRIu16, (*chunksize));
4769 break;
4771 default:
4773 cs_log("Unknown socket command received: 0x%08X", opcode);
4774 (*chunksize) = 1;
4775 (*data_len) = 1;
4776 break;
4780 if((*chunksize) < 1)
4782 (*chunksize) = 1;
4783 (*data_len) = 1;
4787 static void dvbapi_handlesockmsg(uchar* mbuf, uint16_t chunksize, uint16_t data_len, int32_t connfd, uint16_t* client_proto_version)
4789 uint32_t opcode = b2i(4, mbuf); //get the client opcode (4 bytes)
4791 if((opcode & 0xFFFFF000) == DVBAPI_AOT_CA)
4793 switch(opcode & 0xFFFFFF00)
4795 case DVBAPI_AOT_CA_PMT:
4797 if(data_len < 5)
4799 cs_log("Error: packet DVBAPI_AOT_CA_PMT is too short!");
4800 break;
4803 cs_log_dbg(D_DVBAPI, "PMT Update on socket %d.", connfd);
4804 cs_log_dump_dbg(D_DVBAPI, mbuf, chunksize, "Parsing PMT object:");
4806 dvbapi_parse_capmt(mbuf + (chunksize - data_len), data_len, connfd, NULL, 0, 0, *client_proto_version);
4807 break;
4809 case (DVBAPI_AOT_CA_STOP & 0xFFFFFF00):
4811 // 9F 80 3f 04 83 02 00 <demux index>
4812 if(opcode != DVBAPI_AOT_CA_STOP)
4814 cs_log_dbg(D_DVBAPI, "dvbapi_handlesockmsg(): DVBAPI_AOT_CA opcode unknown: %08X", opcode);
4815 break;
4817 int32_t i;
4819 if(data_len < 4)
4821 cs_log("Error: packet DVBAPI_AOT_CA_STOP is too short!");
4822 break;
4825 // ipbox fix
4826 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX || cfg.dvbapi_listenport)
4828 int32_t demux_index = mbuf[7];
4829 for(i = 0; i < MAX_DEMUX; i++)
4831 // 0xff demux_index is a wildcard => close all related demuxers
4832 if(demux_index == 0xff)
4834 if(demux[i].socket_fd == connfd)
4836 dvbapi_stop_descrambling(i);
4839 else if (demux[i].demux_index == demux_index)
4841 dvbapi_stop_descrambling(i);
4842 break;
4845 if (cfg.dvbapi_boxtype == BOXTYPE_IPBOX)
4847 // check do we have any demux running on this fd
4848 int16_t execlose = 1;
4849 for(i = 0; i < MAX_DEMUX; i++)
4851 if(demux[i].socket_fd == connfd)
4853 execlose = 0;
4854 break;
4857 if(execlose)
4859 int32_t ret = close(connfd);
4860 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4864 else
4866 if(cfg.dvbapi_pmtmode != 6)
4868 int32_t ret = close(connfd);
4869 if(ret < 0) { cs_log("ERROR: Could not close PMT fd (errno=%d %s)", errno, strerror(errno)); }
4872 break;
4874 default:
4876 cs_log_dbg(D_DVBAPI, "dvbapi_handlesockmsg(): DVBAPI_AOT_CA opcode unknown: %08X", opcode);
4877 break;
4881 else switch(opcode)
4883 case DVBAPI_FILTER_DATA:
4885 if(data_len < 1)
4887 cs_log("Error: packet DVBAPI_FILTER_DATA is too short!");
4888 break;
4891 int32_t demux_id = mbuf[4];
4892 int32_t filter_num = mbuf[5];
4894 if(demux_id < 0 || demux_id >= MAX_DEMUX)
4896 cs_log("dvbapi_handlesockmsg(): error - received invalid demux_id (%d)", demux_id);
4897 break;
4900 if(filter_num < 0 || filter_num >= MAX_FILTER)
4902 cs_log("dvbapi_handlesockmsg(): error - received invalid filter_num (%d)", filter_num);
4903 break;
4906 dvbapi_process_input(demux_id, filter_num, mbuf + 6, data_len + 3);
4907 break;
4909 case DVBAPI_CLIENT_INFO:
4911 uint16_t client_proto = b2i(2, mbuf + 4);
4913 NULLFREE(last_client_name);
4915 if(cs_malloc(&last_client_name, data_len + 1))
4917 memcpy(last_client_name, &mbuf[7], data_len);
4918 last_client_name[data_len] = 0;
4919 cs_log("Client connected: '%s' (protocol version = %" PRIu16 ")", last_client_name, client_proto);
4922 (*client_proto_version) = client_proto; //setting the global var according to the client
4923 last_client_proto_version = client_proto;
4925 // as a response we are sending our info to the client:
4926 dvbapi_net_send(DVBAPI_SERVER_INFO, connfd, -1, -1, NULL, NULL, NULL, client_proto);
4927 break;
4929 default:
4931 cs_log_dbg(D_DVBAPI, "dvbapi_handlesockmsg(): opcode unknown: %08X", opcode);
4932 cs_log_dump(mbuf, chunksize, "Unknown command:");
4933 break;
4938 static bool dvbapi_handlesockdata(int32_t connfd, uchar* mbuf, uint16_t mbuf_size, uint16_t unhandled_len,
4939 uint16_t* new_unhandled_len, uint16_t* client_proto_version)
4941 int32_t recv_result;
4942 uint16_t chunksize = 1, data_len = 1;
4943 uint8_t packet_count = 0;
4945 uint16_t missing_header_bytes = dvbapi_get_nbof_missing_header_bytes(mbuf, unhandled_len);
4947 if(missing_header_bytes)
4949 // read first few bytes so we know packet type and length
4950 cs_log_dbg(D_TRACE, "%s to read %" PRIu16 " bytes from connection fd %d", (unhandled_len == 0) ? "Trying":"Continue", missing_header_bytes, connfd);
4952 recv_result = dvbapi_recv(connfd, mbuf + unhandled_len, mbuf_size - unhandled_len);
4953 if(recv_result < 1)
4955 (*new_unhandled_len) = unhandled_len;
4956 return (recv_result != -1);
4958 else
4960 unhandled_len += recv_result;
4962 if(unhandled_len < dvbapi_get_nbof_missing_header_bytes(mbuf, unhandled_len))
4964 (*new_unhandled_len) = unhandled_len;
4965 return true;
4972 // we got at least the first few bytes, detect packet type and length, then read the missing bytes
4973 dvbapi_get_packet_size(mbuf, unhandled_len, &chunksize, &data_len);
4975 if(chunksize > mbuf_size)
4977 cs_log("***** WARNING: SOCKET DATA BUFFER OVERFLOW (%" PRIu16 " bytes), PLEASE REPORT! ****** ", chunksize);
4978 (*new_unhandled_len) = 0;
4979 return true;
4982 if(unhandled_len < chunksize) // we are missing some bytes, try to read them
4984 cs_log_dbg(D_TRACE, "Continue to read %d bytes from connection fd %d", chunksize - unhandled_len, connfd);
4986 recv_result = dvbapi_recv(connfd, mbuf + unhandled_len, mbuf_size - unhandled_len);
4987 if(recv_result < 1)
4989 (*new_unhandled_len) = unhandled_len;
4990 return (recv_result != -1);
4992 else
4994 unhandled_len += recv_result;
4996 if(unhandled_len < chunksize)
4998 (*new_unhandled_len) = unhandled_len;
4999 return true;
5004 // we got at least one full packet, handle it, then return
5005 dvbapi_handlesockmsg(mbuf, chunksize, data_len, connfd, client_proto_version);
5007 unhandled_len -= chunksize;
5009 if(unhandled_len > 0)
5011 memmove(mbuf, mbuf + chunksize, unhandled_len);
5014 packet_count++;
5016 } while(dvbapi_get_nbof_missing_header_bytes(mbuf, unhandled_len) == 0 && packet_count < 7);
5018 (*new_unhandled_len) = unhandled_len;
5019 return true;
5022 static void *dvbapi_main_local(void *cli)
5024 int32_t i, j, l;
5025 struct s_client *client = (struct s_client *) cli;
5026 client->thread = pthread_self();
5027 SAFE_SETSPECIFIC(getclient, cli);
5029 dvbapi_client = cli;
5031 int32_t maxpfdsize = (MAX_DEMUX * maxfilter) + MAX_DEMUX + 2;
5032 struct pollfd pfd2[maxpfdsize];
5033 struct timeb start, end; // start time poll, end time poll
5034 #define PMT_SERVER_SOCKET "/tmp/.listen.camd.socket"
5035 struct sockaddr_un saddr;
5036 saddr.sun_family = AF_UNIX;
5037 strncpy(saddr.sun_path, PMT_SERVER_SOCKET, 107);
5038 saddr.sun_path[107] = '\0';
5040 int32_t rc, pfdcount, g, connfd, clilen;
5041 int32_t ids[maxpfdsize], fdn[maxpfdsize], type[maxpfdsize];
5042 struct SOCKADDR servaddr;
5043 ssize_t len = 0;
5044 static const uint16_t mbuf_size = 2048;
5045 uchar *mbuf;
5046 uint16_t unhandled_buf_len[maxpfdsize], unhandled_buf_used[maxpfdsize];
5047 uchar *unhandled_buf[maxpfdsize];
5048 struct s_auth *account;
5049 int32_t ok = 0;
5050 uint16_t client_proto_version[maxpfdsize];
5051 uint16_t unassoc_migrate_pfdindex[MAX_DEMUX];
5053 if(!cs_malloc(&mbuf, sizeof(uchar)*mbuf_size))
5055 return NULL;
5058 for(i = 0; i < maxpfdsize; i++)
5060 unhandled_buf[i] = NULL;
5061 unhandled_buf_len[i] = 0;
5062 unhandled_buf_used[i] = 0;
5064 client_proto_version[i] = 0;
5067 for(account = cfg.account; account != NULL; account = account->next)
5069 if((ok = is_dvbapi_usr(account->usr)))
5070 { break; }
5072 cs_auth_client(client, ok ? account : (struct s_auth *)(-1), "dvbapi");
5074 memset(demux, 0, sizeof(struct demux_s) * MAX_DEMUX);
5075 for(i = 0; i < MAX_DEMUX; i++)
5077 for(j = 0; j < ECM_PIDS; j++)
5079 for(l = 0; l < MAX_STREAM_INDICES; l++)
5081 demux[i].ECMpids[j].index[l] = INDEX_INVALID;
5086 memset(ca_fd, 0, sizeof(ca_fd));
5087 memset(unassoc_fd, 0, sizeof(unassoc_fd));
5088 memset(unassoc_migrate_pfdindex, 0, sizeof(unassoc_migrate_pfdindex));
5090 dvbapi_read_priority();
5091 dvbapi_load_channel_cache();
5092 dvbapi_detect_api();
5094 if(selected_box == -1 || selected_api == -1)
5096 cs_log("ERROR: Could not detect DVBAPI version.");
5097 free(mbuf);
5098 return NULL;
5101 if(cfg.dvbapi_pmtmode == 1)
5102 { disable_pmt_files = 1; }
5104 int32_t listenfd = -1;
5105 if(cfg.dvbapi_boxtype != BOXTYPE_IPBOX_PMT && cfg.dvbapi_pmtmode != 2 && cfg.dvbapi_pmtmode != 5 && cfg.dvbapi_pmtmode != 6)
5107 if (!cfg.dvbapi_listenport)
5108 listenfd = dvbapi_init_listenfd();
5109 else
5110 listenfd = dvbapi_net_init_listenfd();
5111 if(listenfd < 1)
5113 cs_log("ERROR: Could not init socket: (errno=%d: %s)", errno, strerror(errno));
5114 free(mbuf);
5115 return NULL;
5119 SAFE_MUTEX_INIT(&event_handler_lock, NULL);
5121 for(i = 0; i < MAX_DEMUX; i++) // init all demuxers!
5123 demux[i].pidindex = -1;
5124 demux[i].curindex = -1;
5127 if(cfg.dvbapi_pmtmode != 4 && cfg.dvbapi_pmtmode != 5 && cfg.dvbapi_pmtmode != 6)
5129 struct sigaction signal_action;
5130 signal_action.sa_handler = event_handler;
5131 sigemptyset(&signal_action.sa_mask);
5132 signal_action.sa_flags = SA_RESTART;
5133 sigaction(SIGRTMIN + 1, &signal_action, NULL);
5135 dir_fd = open(TMPDIR, O_RDONLY);
5136 if(dir_fd >= 0)
5138 fcntl(dir_fd, F_SETSIG, SIGRTMIN + 1);
5139 fcntl(dir_fd, F_NOTIFY, DN_MODIFY | DN_CREATE | DN_DELETE | DN_MULTISHOT);
5140 event_handler(SIGRTMIN + 1);
5143 else
5145 int32_t ret = start_thread("dvbapi event", dvbapi_event_thread, (void *) dvbapi_client, NULL, 1, 0);
5146 if(ret)
5148 free(mbuf);
5149 return NULL;
5153 if(listenfd != -1)
5155 pfd2[0].fd = listenfd;
5156 pfd2[0].events = (POLLIN | POLLPRI);
5157 type[0] = 1;
5160 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
5161 system("pzapit -rz");
5162 #endif
5163 cs_ftime(&start); // register start time
5164 while(!exit_oscam)
5166 if(pausecam) // for dbox2, STAPI or PC in standby mode dont parse any ecm/emm or try to start next filter
5167 { continue; }
5169 if(cfg.dvbapi_pmtmode == 6)
5171 if(listenfd < 0)
5173 cs_log("PMT6: Trying connect to enigma CA PMT listen socket...");
5174 /* socket init */
5175 if((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
5178 cs_log("socket error (errno=%d %s)", errno, strerror(errno));
5179 listenfd = -1;
5181 else if(connect(listenfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
5183 cs_log("socket connect error (errno=%d %s)", errno, strerror(errno));
5184 close(listenfd);
5185 listenfd = -1;
5187 else
5189 pfd2[0].fd = listenfd;
5190 pfd2[0].events = (POLLIN | POLLPRI);
5191 type[0] = 1;
5192 cs_log("PMT6 CA PMT Server connected on fd %d!", listenfd);
5195 if(listenfd == -1) // not connected!
5197 cs_sleepms(1000);
5198 continue; // start fresh connect attempt!
5202 pfdcount = (listenfd > -1) ? 1 : 0;
5204 for(i = 0; i < MAX_DEMUX; i++)
5206 // add client fd's which are not yet associated with the demux but needs to be polled for data
5207 if (unassoc_fd[i]) {
5208 pfd2[pfdcount].fd = unassoc_fd[i];
5209 pfd2[pfdcount].events = (POLLIN | POLLPRI);
5210 g = unassoc_migrate_pfdindex[i];
5211 // migrate from another poll index
5212 if (g-- > 0) {
5213 if (g != pfdcount) {
5214 client_proto_version[pfdcount] = client_proto_version[g];
5215 client_proto_version[g] = 0;
5216 unhandled_buf_len[pfdcount] = unhandled_buf_len[g];
5217 unhandled_buf_len[g] = 0;
5218 unhandled_buf_used[pfdcount] = unhandled_buf_used[g];
5219 unhandled_buf_used[g] = 0;
5220 unhandled_buf[pfdcount] = unhandled_buf[g];
5221 unhandled_buf[g] = NULL;
5223 unassoc_migrate_pfdindex[i] = 0;
5225 type[pfdcount++] = 1;
5228 if(demux[i].program_number == 0) { continue; } // only evalutate demuxers that have channels assigned
5230 uint32_t ecmcounter = 0, emmcounter = 0;
5231 for(g = 0; g < maxfilter; g++)
5233 if(demux[i].demux_fd[g].fd <= 0) continue; // deny obvious invalid fd!
5235 if(!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX && selected_api != STAPI && selected_api != COOLAPI)
5237 pfd2[pfdcount].fd = demux[i].demux_fd[g].fd;
5238 pfd2[pfdcount].events = (POLLIN | POLLPRI);
5239 ids[pfdcount] = i;
5240 fdn[pfdcount] = g;
5241 type[pfdcount++] = 0;
5243 if(demux[i].demux_fd[g].type == TYPE_ECM) { ecmcounter++; } // count ecm filters to see if demuxing is possible anyway
5244 if(demux[i].demux_fd[g].type == TYPE_EMM) { emmcounter++; } // count emm filters also
5246 if(ecmcounter != demux[i].old_ecmfiltercount || emmcounter != demux[i].old_emmfiltercount) // only produce log if something changed
5248 cs_log_dbg(D_DVBAPI, "Demuxer %d has %d ecmpids, %d streampids, %d ecmfilters and %d of max %d emmfilters", i, demux[i].ECMpidcount,
5249 demux[i].STREAMpidcount, ecmcounter, emmcounter, demux[i].max_emm_filter);
5250 demux[i].old_ecmfiltercount = ecmcounter; // save new amount of ecmfilters
5251 demux[i].old_emmfiltercount = emmcounter; // save new amount of emmfilters
5254 // delayed emm start for non irdeto caids, start emm cat if not already done for this demuxer!
5256 struct timeb now;
5257 cs_ftime(&now);
5258 int64_t gone;
5259 int8_t do_emm_start = (cfg.dvbapi_au > 0 && demux[i].emm_filter == -1 && demux[i].EMMpidcount == 0 && emmcounter == 0);
5260 int8_t do_sdt_start = (cfg.dvbapi_read_sdt && demux[i].sdt_filter == -1 && cfg.dvbapi_boxtype != BOXTYPE_SAMYGO);
5262 if(do_emm_start || do_sdt_start)
5264 gone = comp_timeb(&now, &demux[i].emmstart);
5266 if(gone > 30*1000){
5268 if(do_emm_start) {
5269 cs_ftime(&demux[i].emmstart); // trick to let emm fetching start after 30 seconds to speed up zapping
5270 dvbapi_start_filter(i, demux[i].pidindex, 0x001, 0x001, 0x01, 0x01, 0xFF, 0, TYPE_EMM); //CAT
5274 if(gone > 10*1000){
5275 if(do_sdt_start)
5277 dvbapi_start_sdt_filter(i);
5282 //early start for irdeto since they need emm before ecm (pmt emmstart = 1 if detected caid 0x06)
5283 int32_t emmstarted = demux[i].emm_filter;
5284 if(cfg.dvbapi_au && demux[i].EMMpidcount > 0) // check every time since share readers might give us new filters due to hexserial change
5286 if(!emmcounter && emmstarted == -1)
5288 demux[i].emmstart = now;
5289 dvbapi_start_emm_filter(i); // start emmfiltering if emmpids are found
5291 else
5293 gone = comp_timeb(&now, &demux[i].emmstart);
5294 if(gone > 30*1000)
5296 demux[i].emmstart = now;
5297 dvbapi_start_emm_filter(i); // start emmfiltering delayed if filters already were running
5298 rotate_emmfilter(i); // rotate active emmfilters
5303 if(ecmcounter == 0 && demux[i].ECMpidcount > 0) // Restart decoding all caids we have ecmpids but no ecm filters!
5306 int32_t started = 0;
5308 for(g = 0; g < demux[i].ECMpidcount; g++) // avoid race: not all pids are asked and checked out yet!
5310 if(demux[i].ECMpids[g].checked == 0 && demux[i].ECMpids[g].status >= 0) // check if prio run is done
5312 dvbapi_try_next_caid(i, 0); // not done, so start next prio pid
5313 started = 1;
5314 break;
5317 if(started) { continue; } // if started a filter proceed with next demuxer
5319 if(g == demux[i].ECMpidcount) // all usable pids (with prio) are tried, lets start over again without prio!
5321 for(g = 0; g < demux[i].ECMpidcount; g++) // avoid race: not all pids are asked and checked out yet!
5323 if(demux[i].ECMpids[g].checked == 2 && demux[i].ECMpids[g].status >= 0) // check if noprio run is done
5325 demux[i].ECMpids[g].irdeto_curindex = 0xFE;
5326 demux[i].ECMpids[g].irdeto_maxindex = 0;
5327 demux[i].ECMpids[g].irdeto_cycle = 0xFE;
5328 demux[i].ECMpids[g].tries = 0xFE;
5329 demux[i].ECMpids[g].table = 0;
5330 demux[i].ECMpids[g].CHID = 0x10000; // remove chid prio
5331 dvbapi_try_next_caid(i, 2); // not done, so start next no prio pid
5332 started = 1;
5333 break;
5337 if(started) { continue; } // if started a filter proceed with next demuxer
5339 if(g == demux[i].ECMpidcount) // all usable pids are tried, lets start over again!
5341 if(demux[i].decodingtries == -1) // first redecoding attempt?
5343 cs_ftime(&demux[i].decstart);
5344 for(g = 0; g < demux[i].ECMpidcount; g++) // reinit some used things from second run (without prio)
5346 demux[i].ECMpids[g].checked = 0;
5347 demux[i].ECMpids[g].irdeto_curindex = 0xFE;
5348 demux[i].ECMpids[g].irdeto_maxindex = 0;
5349 demux[i].ECMpids[g].irdeto_cycle = 0xFE;
5350 demux[i].ECMpids[g].table = 0;
5351 demux[i].decodingtries = 0;
5352 dvbapi_edit_channel_cache(i, g, 0); // remove this pid from channelcache since we had no founds on any ecmpid!
5355 uint8_t number_of_enabled_pids = 0;
5356 demux[i].decodingtries++;
5357 dvbapi_resort_ecmpids(i);
5359 for(g = 0; g < demux[i].ECMpidcount; g++) // count number of enabled pids!
5361 if(demux[i].ECMpids[g].status >= 0) number_of_enabled_pids++;
5363 if(!number_of_enabled_pids)
5365 if(demux[i].decodingtries == 10)
5367 demux[i].decodingtries = 0;
5368 cs_log("Demuxer %d no enabled matching ecmpids -> decoding is waiting for matching readers!",i);
5371 else
5373 cs_ftime(&demux[i].decend);
5374 demux[i].decodingtries = -1; // reset to first run again!
5375 gone = comp_timeb(&demux[i].decend, &demux[i].decstart);
5376 cs_log("Demuxer %d restarting decodingrequests after %"PRId64" ms with %d enabled and %d disabled ecmpids!", i, gone, number_of_enabled_pids,
5377 (demux[i].ECMpidcount-number_of_enabled_pids));
5378 dvbapi_try_next_caid(i, 0);
5383 if(demux[i].socket_fd > 0 && cfg.dvbapi_pmtmode != 6)
5385 rc = 0;
5386 for(j = 0; j < pfdcount; j++)
5388 if(pfd2[j].fd == demux[i].socket_fd)
5390 rc = 1;
5391 break;
5394 if(rc == 1) { continue; }
5396 pfd2[pfdcount].fd = demux[i].socket_fd;
5397 pfd2[pfdcount].events = (POLLIN | POLLPRI);
5398 ids[pfdcount] = i;
5399 type[pfdcount++] = 1;
5403 rc = 0;
5404 while(!(listenfd == -1 && cfg.dvbapi_pmtmode == 6))
5406 rc = poll(pfd2, pfdcount, 500);
5407 if(rc < 0) // error occured while polling for fd's with fresh data
5409 if(errno == EINTR || errno == EAGAIN) // try again in case of interrupt
5411 continue;
5413 cs_log("ERROR: error on poll of %d fd's (errno=%d %s)", pfdcount, errno, strerror(errno));
5414 break;
5416 else
5418 break;
5422 if(rc > 0)
5424 cs_ftime(&end); // register end time
5425 int64_t timeout = comp_timeb(&end, &start);
5426 if (timeout < 0) {
5427 cs_log("*** WARNING: BAD TIME AFFECTING WHOLE OSCAM ECM HANDLING ****");
5429 cs_log_dbg(D_TRACE, "New events occurred on %d of %d handlers after %"PRId64" ms inactivity", rc, pfdcount, timeout);
5430 cs_ftime(&start); // register new start time for next poll
5433 for(i = 0; i < pfdcount && rc > 0; i++)
5435 if(pfd2[i].revents == 0) { continue; } // skip sockets with no changes
5436 rc--; //event handled!
5437 cs_log_dbg(D_TRACE, "Now handling fd %d that reported event %d", pfd2[i].fd, pfd2[i].revents);
5439 if(pfd2[i].revents & (POLLHUP | POLLNVAL | POLLERR))
5441 if(type[i] == 1)
5443 for(j = 0; j < MAX_DEMUX; j++)
5445 if(demux[j].socket_fd == pfd2[i].fd) // if listenfd closes stop all assigned decoding!
5447 dvbapi_stop_descrambling(j);
5450 // remove from unassoc_fd when necessary
5451 if (unassoc_fd[j] == pfd2[i].fd)
5453 unassoc_fd[j] = 0;
5456 int32_t ret = close(pfd2[i].fd);
5457 if(ret < 0 && errno != 9) { cs_log("ERROR: Could not close demuxer socket fd (errno=%d %s)", errno, strerror(errno)); }
5458 if(pfd2[i].fd == listenfd && cfg.dvbapi_pmtmode == 6)
5460 listenfd = -1;
5463 cs_log_dbg(D_DVBAPI, "Socket %d reported hard connection close", pfd2[i].fd);
5465 else // type = 0
5467 int32_t demux_index = ids[i];
5468 int32_t n = fdn[i];
5470 if(cfg.dvbapi_boxtype != BOXTYPE_SAMYGO)
5472 dvbapi_stop_filternum(demux_index, n); // stop filter since its giving errors and wont return anything good.
5474 else
5476 int32_t ret, pid;
5477 uchar filter[32];
5478 struct dmx_sct_filter_params sFP;
5480 cs_log_dbg(D_DVBAPI, "re-opening connection to demux socket");
5481 close(demux[demux_index].demux_fd[n].fd);
5482 demux[demux_index].demux_fd[n].fd = -1;
5484 ret = dvbapi_open_device(0, demux[demux_index].demux_index, demux[demux_index].adapter_index);
5485 if(ret != -1)
5487 demux[demux_index].demux_fd[n].fd = ret;
5489 pid = demux[demux_index].curindex;
5491 memset(filter, 0, 32);
5492 memset(&sFP, 0, sizeof(sFP));
5494 filter[0] = 0x80;
5495 filter[16] = 0xF0;
5497 sFP.pid = demux[demux_index].ECMpids[pid].ECM_PID;
5498 sFP.timeout = 3000;
5499 sFP.flags = DMX_IMMEDIATE_START;
5500 memcpy(sFP.filter.filter, filter, 16);
5501 memcpy(sFP.filter.mask, filter + 16, 16);
5502 ret = dvbapi_ioctl(demux[demux_index].demux_fd[n].fd, DMX_SET_FILTER, &sFP);
5505 if(ret == -1)
5506 dvbapi_stop_filternum(demux_index, n); // stop filter since its giving errors and wont return anything good.
5509 continue; // continue with other events
5512 if(pfd2[i].revents & (POLLIN | POLLPRI))
5514 if(type[i] == 1)
5516 connfd = -1; // initially no socket to read from
5517 uint8_t add_to_poll = 0; // we may need to additionally poll this socket when no PMT data comes in
5519 if (pfd2[i].fd == listenfd)
5521 if (cfg.dvbapi_pmtmode == 6) {
5522 connfd = listenfd;
5523 disable_pmt_files = 1;
5524 } else {
5525 clilen = sizeof(servaddr);
5526 connfd = accept(listenfd, (struct sockaddr *)&servaddr, (socklen_t *)&clilen);
5527 cs_log_dbg(D_DVBAPI, "new socket connection fd: %d", connfd);
5528 if (cfg.dvbapi_listenport)
5530 //update webif data
5531 client->ip = SIN_GET_ADDR(servaddr);
5532 client->port = ntohs(SIN_GET_PORT(servaddr));
5534 add_to_poll = 1;
5536 if(cfg.dvbapi_pmtmode == 3 || cfg.dvbapi_pmtmode == 0) { disable_pmt_files = 1; }
5538 if(connfd <= 0)
5539 cs_log_dbg(D_DVBAPI, "accept() returns error on fd event %d (errno=%d %s)", pfd2[i].revents, errno, strerror(errno));
5542 else
5544 connfd = pfd2[i].fd;
5547 //reading and completing data from socket
5548 if (connfd > 0) {
5550 if(unhandled_buf_used[i])
5552 memcpy(mbuf, unhandled_buf[i], unhandled_buf_used[i]);
5555 if(!dvbapi_handlesockdata(connfd, mbuf, mbuf_size, unhandled_buf_used[i], &unhandled_buf_used[i], &client_proto_version[i]))
5557 unhandled_buf_used[i] = 0;
5559 //client disconnects, stop all assigned decoding
5560 cs_log_dbg(D_DVBAPI, "Socket %d reported connection close", connfd);
5561 int active_conn = 0; //other active connections counter
5562 add_to_poll = 0;
5564 for (j = 0; j < MAX_DEMUX; j++)
5566 if (demux[j].socket_fd == connfd)
5568 dvbapi_stop_descrambling(j);
5570 else if (demux[j].socket_fd)
5572 active_conn++;
5575 // remove from unassoc_fd when necessary
5576 if (unassoc_fd[j] == connfd)
5578 unassoc_fd[j] = 0;
5582 close(connfd);
5583 connfd = -1;
5585 if (!active_conn && (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)) //last connection closed
5587 if (cfg.dvbapi_listenport)
5589 //update webif data
5590 client->ip = get_null_ip();
5591 client->port = 0;
5595 continue;
5598 if(unhandled_buf_used[i])
5600 if(unhandled_buf_used[i] > unhandled_buf_len[i])
5602 NULLFREE(unhandled_buf[i]);
5604 unhandled_buf_len[i] = unhandled_buf_used[i] < 128 ? 128 : unhandled_buf_used[i];
5606 if(!cs_malloc(&unhandled_buf[i], sizeof(uchar)*unhandled_buf_len[i]))
5608 unhandled_buf_len[i] = 0;
5609 unhandled_buf_used[i] = 0;
5610 continue;
5614 memcpy(unhandled_buf[i], mbuf, unhandled_buf_used[i]);
5617 // if the connection is new and we read no PMT data, then add it to the poll,
5618 // otherwise this socket will not be checked with poll when data arives
5619 // because fd it is not yet assigned with the demux
5620 if (add_to_poll) {
5621 for (j = 0; j < MAX_DEMUX; j++) {
5622 if (!unassoc_fd[j]) {
5623 unassoc_fd[j] = connfd;
5624 unassoc_migrate_pfdindex[j] = i + 1;
5625 break;
5631 else // type==0
5633 int32_t demux_index = ids[i];
5634 int32_t n = fdn[i];
5636 if((int)demux[demux_index].demux_fd[n].fd != pfd2[i].fd) { continue; } // filter already killed, no need to process this data!
5638 len = dvbapi_read_device(pfd2[i].fd, mbuf, mbuf_size);
5639 if(len < 0) // serious filterdata read error
5641 dvbapi_stop_filternum(demux_index, n); // stop filter since its giving errors and wont return anything good.
5642 maxfilter--; // lower maxfilters to avoid this with new filter setups!
5643 continue;
5645 if(!len) // receiver internal filterbuffer overflow
5647 memset(mbuf, 0, mbuf_size);
5650 dvbapi_process_input(demux_index, n, mbuf, len);
5652 continue; // continue with other events!
5657 for(j = 0; j < maxpfdsize; j++)
5659 NULLFREE(unhandled_buf[j]);
5661 free(mbuf);
5662 return NULL;
5665 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)
5667 int32_t n;
5668 int8_t cwEmpty = 0;
5669 unsigned char nullcw[8];
5670 memset(nullcw, 0, 8);
5671 ca_descr_t ca_descr;
5672 ca_descr_mode_t ca_descr_mode;
5674 memset(&ca_descr, 0, sizeof(ca_descr));
5675 memset(&ca_descr_mode, 0, sizeof(ca_descr_mode_t));
5677 if(memcmp(demux[demux_id].lastcw[0], nullcw, 8) == 0
5678 && memcmp(demux[demux_id].lastcw[1], nullcw, 8) == 0)
5679 { cwEmpty = 1; } // to make sure that both cws get written on constantcw
5682 for(n = 0; n < 2; n++)
5684 char lastcw[9 * 3];
5685 char newcw[9 * 3];
5686 cs_hexdump(0, demux[demux_id].lastcw[n], 8, lastcw, sizeof(lastcw));
5687 cs_hexdump(0, cw + (n * 8), 8, newcw, sizeof(newcw));
5689 if((memcmp(cw + (n * 8), demux[demux_id].lastcw[n], 8) != 0 || cwEmpty)
5690 && memcmp(cw + (n * 8), nullcw, 8) != 0) // check if already delivered and new cw part is valid!
5692 ca_index_t idx = dvbapi_ca_setpid(demux_id, pid, stream_id, (algo == CA_ALGO_DES)); // prepare ca
5693 if (idx == INDEX_INVALID) return; // return on no index!
5695 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
5696 ca_descr.index = idx;
5697 ca_descr.parity = n;
5698 memcpy(demux[demux_id].lastcw[n], cw + (n * 8), 8);
5699 memcpy(ca_descr.cw, cw + (n * 8), 8);
5700 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);
5701 coolapi_write_cw(demux[demux_id].ca_mask, demux[demux_id].STREAMpids, demux[demux_id].STREAMpidcount, &ca_descr);
5702 #else
5703 int32_t i, j, write_cw = 0;
5704 ca_index_t usedidx, lastidx;
5706 for(i = 0; i < MAX_DEMUX; i++)
5708 if(!(demux[demux_id].ca_mask & (1 << i))) continue; // ca not in use by this demuxer!
5710 lastidx = INDEX_INVALID;
5712 for(j = 0; j < demux[demux_id].STREAMpidcount; j++)
5714 write_cw = 0;
5715 if(!demux[demux_id].ECMpids[pid].streams || ((demux[demux_id].ECMpids[pid].streams & (1 << j)) == (uint) (1 << j)))
5717 usedidx = is_ca_used(i, demux[demux_id].STREAMpids[j]);
5718 if(usedidx != INDEX_INVALID)
5720 if(idx != usedidx)
5722 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]);
5723 continue; // if not used for descrambling -> skip!
5725 else
5727 if(usedidx == lastidx)
5729 cs_log_dbg(D_DVBAPI,"Demuxer %d ca%d is using index %d for streampid %04X -> skip, %s part of cw already written!",
5730 demux_id, i, usedidx, demux[demux_id].STREAMpids[j], (n == 1 ? "even" : "odd"));
5731 continue;
5733 cs_log_dbg(D_DVBAPI,"Demuxer %d ca%d is using index %d for streampid %04X -> write %s part of cw!",
5734 demux_id, i, usedidx, demux[demux_id].STREAMpids[j], (n == 1 ? "even" : "odd"));
5735 write_cw = 1;
5739 if(!write_cw) { continue; } // no need to write the cw since this ca isnt using it!
5741 lastidx = usedidx;
5742 ca_descr.index = usedidx;
5743 ca_descr.parity = n;
5744 memcpy(demux[demux_id].lastcw[n], cw + (n * 8), 8);
5745 memcpy(ca_descr.cw, cw + (n * 8), 8);
5746 cs_log_dbg(D_DVBAPI, "Demuxer %d writing %s part (%s) of controlword, replacing expired (%s)", demux_id, (n == 1 ? "even" : "odd"), newcw, lastcw);
5747 cs_log_dbg(D_DVBAPI, "Demuxer %d write cw%d index: %d (ca%d)", demux_id, n, ca_descr.index, i);
5749 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
5750 dvbapi_net_send(DVBAPI_CA_SET_DESCR, demux[demux_id].socket_fd, demux_id, -1 /*unused*/, (unsigned char *) &ca_descr, NULL, NULL, demux[demux_id].client_proto_version);
5751 else
5753 if(ca_fd[i] <= 0)
5755 ca_fd[i] = dvbapi_open_device(1, i, demux[demux_id].adapter_index);
5756 if(ca_fd[i] <= 0) { continue; }
5758 if (dvbapi_ioctl(ca_fd[i], CA_SET_DESCR, &ca_descr) < 0)
5760 cs_log("ERROR: ioctl(CA_SET_DESCR): %s", strerror(errno));
5764 if(cfg.dvbapi_extended_cw_api == 1)
5766 ca_descr_mode.index = usedidx;
5767 ca_descr_mode.algo = algo;
5768 ca_descr_mode.cipher_mode = cipher_mode;
5770 if(cfg.dvbapi_boxtype == BOXTYPE_PC || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
5771 dvbapi_net_send(DVBAPI_CA_SET_DESCR_MODE, demux[demux_id].socket_fd, demux_id, -1 /*unused*/, (unsigned char *) &ca_descr_mode, NULL, NULL, demux[demux_id].client_proto_version);
5772 else
5774 if(ca_fd[i] <= 0)
5776 ca_fd[i] = dvbapi_open_device(1, i, demux[demux_id].adapter_index);
5777 if(ca_fd[i] <= 0) { continue; }
5779 if (dvbapi_ioctl(ca_fd[i], CA_SET_DESCR_MODE, &ca_descr_mode) < 0)
5781 cs_log("ERROR: ioctl(CA_SET_DESCR_MODE): %s", strerror(errno));
5787 #endif
5792 void delayer(ECM_REQUEST *er, uint32_t delay)
5794 if(delay <= 0) { return; }
5796 struct timeb tpe;
5797 cs_ftime(&tpe);
5798 int64_t gone = comp_timeb(&tpe, &er->tps);
5799 if( gone < delay)
5801 cs_log_dbg(D_DVBAPI, "delayer: gone=%"PRId64" ms, cfg=%d ms -> delay=%"PRId64" ms", gone, delay, delay - gone);
5802 cs_sleepms(delay - gone);
5806 void dvbapi_send_dcw(struct s_client *client, ECM_REQUEST *er)
5808 int32_t i, j, k, handled = 0;
5810 for(i = 0; i < MAX_DEMUX; i++)
5812 uint32_t nocw_write = 0; // 0 = write cw, 1 = dont write cw to hardware demuxer
5813 if(demux[i].program_number == 0) { continue; } // ignore empty demuxers
5814 if(demux[i].program_number != er->srvid) { continue; } // skip ecm response for other srvid
5816 #ifdef WITH_STAPI5
5817 if(strcmp(dev_list[demux[i].dev_index].name, er->dev_name) != 0) { continue; } // skip request if PTI device doesn't match request
5818 #endif
5820 demux[i].rdr = er->selected_reader;
5821 for(j = 0; j < demux[i].ECMpidcount; j++) // check for matching ecmpid
5823 if((demux[i].ECMpids[j].CAID == er->caid || demux[i].ECMpids[j].CAID == er->ocaid)
5824 && demux[i].ECMpids[j].ECM_PID == er->pid
5825 && demux[i].ECMpids[j].PROVID == er->prid
5826 && demux[i].ECMpids[j].VPID == er->vpid)
5827 { break; }
5829 if(j == demux[i].ECMpidcount) { continue; } // ecm response srvid ok but no matching ecmpid, perhaps this for other demuxer
5831 cs_log_dbg(D_DVBAPI, "Demuxer %d %scontrolword received for PID %d CAID %04X PROVID %06X ECMPID %04X CHID %04X VPID %04X", i,
5832 (er->rc >= E_NOTFOUND ? "no " : ""), j, er->caid, er->prid, er->pid, er->chid, er->vpid);
5834 uint32_t status = dvbapi_check_ecm_delayed_delivery(i, er);
5836 uint32_t comparecw0 = 0, comparecw1 = 0;
5837 char ecmd5[17 * 3];
5838 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
5840 if(status == 1 && er->rc) // wrong ecmhash
5842 cs_log_dbg(D_DVBAPI, "Demuxer %d not interested in response ecmhash %s (requested different one)", i, ecmd5);
5843 continue;
5845 if(status == 2) // no filter
5847 cs_log_dbg(D_DVBAPI, "Demuxer %d not interested in response ecmhash %s (filter already killed)", i, ecmd5);
5848 continue;
5850 if(status == 5) // empty cw
5852 cs_log_dbg(D_DVBAPI, "Demuxer %d not interested in response ecmhash %s (delivered cw is empty!)", i, ecmd5);
5853 nocw_write = 1;
5854 if(er->rc < E_NOTFOUND) { er->rc = E_NOTFOUND; }
5857 if((status == 0 || status == 3 || status == 4) && er->rc < E_NOTFOUND) // 0=matching ecm hash, 2=no filter, 3=table reset, 4=cache-ex response
5859 if(memcmp(er->cw, demux[i].lastcw[0], 8) == 0 && memcmp(er->cw + 8, demux[i].lastcw[1], 8) == 0) // check for matching controlword
5861 comparecw0 = 1;
5863 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
5865 comparecw1 = 1;
5867 if(comparecw0 == 1 || comparecw1 == 1)
5869 cs_log_dbg(D_DVBAPI, "Demuxer %d duplicate controlword ecm response hash %s (duplicate controlword!)", i, ecmd5);
5870 nocw_write = 1;
5874 if(status == 3) // table reset
5876 cs_log_dbg(D_DVBAPI, "Demuxer %d luckyshot new controlword ecm response hash %s (ecm table reset)", i, ecmd5);
5879 if(status == 4) // no check on cache-ex responses!
5881 cs_log_dbg(D_DVBAPI, "Demuxer %d new controlword from cache-ex reader (no ecmhash check possible)", i);
5884 handled = 1; // mark this ecm response as handled
5885 if(er->rc < E_NOTFOUND && cfg.dvbapi_requestmode == 0 && (demux[i].pidindex == -1) && er->caid != 0)
5887 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry flag
5888 demux[i].ECMpids[j].irdeto_cycle = 0xFE; // reset irdetocycle
5889 demux[i].pidindex = j; // set current index as *the* pid to descramble
5890 demux[i].ECMpids[j].checked = 4;
5891 cs_log_dbg(D_DVBAPI, "Demuxer %d descrambling PID %d CAID %04X PROVID %06X ECMPID %04X CHID %02X VPID %04X",
5892 i, demux[i].pidindex, er->caid, er->prid, er->pid, er->chid, er->vpid);
5895 if(er->rc < E_NOTFOUND && cfg.dvbapi_requestmode == 1 && er->caid != 0) // FOUND
5897 SAFE_MUTEX_LOCK(&demux[i].answerlock); // only process one ecm answer
5898 if(demux[i].ECMpids[j].checked != 4)
5901 int32_t t, o, ecmcounter = 0;
5902 int32_t oldpidindex = demux[i].pidindex;
5903 demux[i].pidindex = j; // set current ecmpid as the new pid to descramble
5904 if(oldpidindex != -1)
5906 for(k = 0; k < MAX_STREAM_INDICES; k++)
5908 demux[i].ECMpids[j].index[k] = demux[i].ECMpids[oldpidindex].index[k]; // swap index with lower status pid that was descrambling
5909 demux[i].ECMpids[j].useMultipleIndices = demux[i].ECMpids[oldpidindex].useMultipleIndices;
5913 for(t = 0; t < demux[i].ECMpidcount; t++) //check this pid with controlword FOUND for higher status:
5915 if(t != j && demux[i].ECMpids[j].status >= demux[i].ECMpids[t].status)
5917 for(o = 0; o < maxfilter; o++) // check if ecmfilter is in use & stop all ecmfilters of lower status pids
5919 if(demux[i].demux_fd[o].fd > 0 && demux[i].demux_fd[o].type == TYPE_ECM && (demux[i].demux_fd[o].pidindex == t))
5921 dvbapi_stop_filternum(i, o); // ecmfilter belongs to lower status pid -> kill!
5924 dvbapi_edit_channel_cache(i, t, 0); // remove lowerstatus pid from channelcache
5925 demux[i].ECMpids[t].checked = 4; // mark index t as low status
5930 for(o = 0; o < maxfilter; o++) if(demux[i].demux_fd[o].type == TYPE_ECM) { ecmcounter++; } // count all ecmfilters
5932 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry flag
5933 demux[i].ECMpids[j].irdeto_cycle = 0xFE; // reset irdetocycle
5935 if(ecmcounter == 1) // if total found running ecmfilters is 1 -> we found the "best" pid
5937 dvbapi_edit_channel_cache(i, j, 1);
5938 demux[i].ECMpids[j].checked = 4; // mark best pid last ;)
5941 cs_log_dbg(D_DVBAPI, "Demuxer %d descrambling PID %d CAID %04X PROVID %06X ECMPID %04X CHID %02X VPID %04X",
5942 i, demux[i].pidindex, er->caid, er->prid, er->pid, er->chid, er->vpid);
5944 SAFE_MUTEX_UNLOCK(&demux[i].answerlock); // and release it!
5947 if(er->rc >= E_NOTFOUND) // not found on requestmode 0 + 1
5949 if(er->rc == E_SLEEPING)
5951 dvbapi_stop_descrambling(i);
5952 return;
5955 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match(i, j, 'p');
5957 if(forceentry && forceentry->force) // forced pid? keep trying the forced ecmpid!
5959 if(!caid_is_irdeto(er->caid) || forceentry->chid < 0x10000) //all cas or irdeto cas with forced prio chid
5961 demux[i].ECMpids[j].table = 0;
5962 dvbapi_set_section_filter(i, er, -1);
5963 continue;
5965 else // irdeto cas without chid prio forced
5967 if(demux[i].ECMpids[j].irdeto_curindex == 0xFE) { demux[i].ECMpids[j].irdeto_curindex = 0x00; } // init irdeto current index to first one
5968 if(!(demux[i].ECMpids[j].irdeto_curindex + 1 > demux[i].ECMpids[j].irdeto_maxindex)) // check for last / max chid
5970 cs_log_dbg(D_DVBAPI, "Demuxer %d trying next irdeto chid of FORCED PID %d CAID %04X PROVID %06X ECMPID %04X", i,
5971 j, er->caid, er->prid, er->pid);
5972 demux[i].ECMpids[j].irdeto_curindex++; // irdeto index one up
5973 demux[i].ECMpids[j].table = 0;
5974 dvbapi_set_section_filter(i, er, -1);
5975 continue;
5980 // in case of timeout or fatal LB event give this pid another try but no more than 1 try
5981 if((er->rc == E_TIMEOUT || (er->rcEx && er->rcEx <= E2_CCCAM_NOCARD)) && demux[i].ECMpids[j].tries == 0xFE)
5983 demux[i].ECMpids[j].tries-=0x07;
5984 demux[i].ECMpids[j].table = 0;
5985 dvbapi_set_section_filter(i, er, -1);
5986 continue;
5988 else // all not found responses exception: first timeout response and first fatal loadbalancer response
5990 demux[i].ECMpids[j].CHID = 0x10000; // get rid of this prio chid since it failed!
5991 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry
5994 if(caid_is_irdeto(er->caid))
5996 if(demux[i].ECMpids[j].irdeto_curindex == 0xFE) { demux[i].ECMpids[j].irdeto_curindex = 0x00; } // init irdeto current index to first one
5997 if(!(demux[i].ECMpids[j].irdeto_curindex + 1 > demux[i].ECMpids[j].irdeto_maxindex)) // check for last / max chid
5999 cs_log_dbg(D_DVBAPI, "Demuxer %d trying next irdeto chid of PID %d CAID %04X PROVID %06X ECMPID %04X VPID %04X", i,
6000 j, er->caid, er->prid, er->pid, er->vpid);
6001 demux[i].ECMpids[j].irdeto_curindex++; // irdeto index one up
6002 demux[i].ECMpids[j].table = 0;
6003 dvbapi_set_section_filter(i, er, -1);
6004 continue;
6008 dvbapi_edit_channel_cache(i, j, 0); // remove this pid from channelcache
6009 if(demux[i].pidindex == j)
6011 demux[i].pidindex = -1; // current pid delivered a notfound so this pid isnt being used to descramble any longer-> clear pidindex
6013 demux[i].ECMpids[j].irdeto_maxindex = 0;
6014 demux[i].ECMpids[j].irdeto_curindex = 0xFE;
6015 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry flag
6016 demux[i].ECMpids[j].irdeto_cycle = 0xFE; // reset irdetocycle
6017 demux[i].ECMpids[j].table = 0;
6018 demux[i].ECMpids[j].checked = 4; // flag ecmpid as checked
6019 demux[i].ECMpids[j].status = -1; // flag ecmpid as unusable
6020 int32_t found = 1; // setup for first run
6021 int32_t filternum = -1;
6023 while(found > 0) // disable all ecm + emm filters for this notfound
6025 found = 0;
6026 filternum = dvbapi_get_filternum(i, er, TYPE_ECM); // get ecm filternumber
6027 if(filternum > -1) // in case valid filter found
6029 int32_t fd = demux[i].demux_fd[filternum].fd;
6030 if(fd > 0) // in case valid fd
6032 dvbapi_stop_filternum(i, filternum); // stop ecmfilter
6033 found = 1;
6036 if(caid_is_irdeto(er->caid)) // in case irdeto cas stop old emm filters
6038 filternum = dvbapi_get_filternum(i, er, TYPE_EMM); // get emm filternumber
6039 if(filternum > -1) // in case valid filter found
6041 int32_t fd = demux[i].demux_fd[filternum].fd;
6042 if(fd > 0) // in case valid fd
6044 dvbapi_stop_filternum(i, filternum); // stop emmfilter
6045 found = 1;
6051 continue;
6055 // below this should be only run in case of ecm answer is found
6057 uint32_t chid = get_subid(er); // derive current chid in case of irdeto, or a unique part of ecm on other cas systems
6058 demux[i].ECMpids[j].CHID = (chid != 0 ? chid : 0x10000); // if not zero apply, otherwise use no chid value 0x10000
6059 dvbapi_edit_channel_cache(i, j, 1); // do it here to here after the right CHID is registered
6061 //dvbapi_set_section_filter(i, er); is not needed anymore (unsure)
6062 demux[i].ECMpids[j].tries = 0xFE; // reset timeout retry flag
6063 demux[i].ECMpids[j].irdeto_cycle = 0xFE; // reset irdeto cycle
6065 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!
6067 struct s_dvbapi_priority *delayentry = dvbapi_check_prio_match(i, demux[i].pidindex, 'd');
6068 uint32_t delay = 0;
6070 if(delayentry)
6072 if(delayentry->delay < 1000)
6074 delay = delayentry->delay;
6075 cs_log_dbg(D_DVBAPI, "specific delay: write cw %d ms after ecmrequest", delay);
6078 else if (cfg.dvbapi_delayer > 0)
6080 delay = cfg.dvbapi_delayer;
6081 cs_log_dbg(D_DVBAPI, "generic delay: write cw %d ms after ecmrequest", delay);
6084 delayer(er, delay);
6086 switch(selected_api)
6088 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
6089 case STAPI:
6090 stapi_write_cw(i, er->cw, demux[i].STREAMpids, demux[i].STREAMpidcount, demux[i].pmt_file);
6091 break;
6092 #endif
6093 default:
6095 #ifdef WITH_EXTENDED_CW
6097 if(er->cw_ex.mode != demux[i].ECMpids[j].useMultipleIndices)
6099 ca_index_t idx;
6100 for(k = 0; k < demux[i].STREAMpidcount; k++)
6102 idx = demux[i].ECMpids[j].useMultipleIndices ? demux[i].ECMpids[j].index[k] : demux[i].ECMpids[j].index[0];
6103 dvbapi_set_pid(i, k, idx, false, false); // disable streampid
6106 for(k = 0; k < MAX_STREAM_INDICES; k++)
6108 demux[i].ECMpids[j].index[k] = INDEX_INVALID;
6112 if(er->cw_ex.mode == CW_MODE_MULTIPLE_CW)
6114 int32_t key_pos_a = 0;
6115 uint8_t *cw, stream_type;
6117 demux[i].ECMpids[j].useMultipleIndices = 1;
6119 for(k = 0; k < demux[i].STREAMpidcount; k++)
6121 stream_type = demux[i].STREAMpidsType[k];
6123 // Video
6124 if(stream_type == 0x01 || stream_type == 0x02 || stream_type == 0x10 || stream_type == 0x1B
6125 || stream_type == 0x24 || stream_type == 0x42 || stream_type == 0x80 || stream_type == 0xD1
6126 || stream_type == 0xEA)
6128 cw = er->cw;
6130 // Audio
6131 else if(stream_type == 0x03 || stream_type == 0x04 || stream_type == 0x0F || stream_type == 0x11
6132 || stream_type == 0x81 || (stream_type >= 0x83 && stream_type <= 0x87) || stream_type == 0x8A)
6134 cw = er->cw_ex.audio[key_pos_a];
6136 if(key_pos_a < 3)
6138 key_pos_a++;
6141 // Data
6142 else
6144 cw = er->cw_ex.data;
6147 dvbapi_write_cw(i, cw, j, k, er->cw_ex.algo, er->cw_ex.algo_mode);
6150 else
6152 demux[i].ECMpids[j].useMultipleIndices = 0;
6153 dvbapi_write_cw(i, er->cw, j, 0, er->cw_ex.algo, er->cw_ex.algo_mode);
6155 #else
6156 dvbapi_write_cw(i, er->cw, j, 0, CA_ALGO_DVBCSA, CA_MODE_ECB);
6157 #endif
6158 break;
6162 // reset idle-Time
6163 client->last = time((time_t *)0); // ********* TO BE FIXED LATER ON ******
6165 if ((cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX) && demux[i].client_proto_version >= 2)
6166 { dvbapi_net_send(DVBAPI_ECM_INFO, demux[i].socket_fd, i, 0, NULL, client, er, demux[i].client_proto_version); }
6167 #ifndef __CYGWIN__
6168 else if (!cfg.dvbapi_listenport && cfg.dvbapi_boxtype != BOXTYPE_PC_NODMX)
6169 #endif
6170 if(cfg.dvbapi_boxtype != BOXTYPE_SAMYGO)
6171 { dvbapi_write_ecminfo_file(client, er, demux[i].lastcw[0], demux[i].lastcw[1]); }
6174 if(handled == 0)
6176 cs_log_dbg(D_DVBAPI, "Unhandled ECM response received for CAID %04X PROVID %06X ECMPID %04X CHID %04X VPID %04X",
6177 er->caid, er->prid, er->pid, er->chid, er->vpid);
6182 static int8_t isValidCW(uint8_t *cw)
6184 uint8_t i;
6185 for(i = 0; i < 16; i += 4)
6187 if(((cw[i] + cw[i + 1] + cw[i + 2]) & 0xff) != cw[i + 3])
6189 return 0;
6192 return 1;
6195 void dvbapi_write_ecminfo_file(struct s_client *client, ECM_REQUEST *er, uint8_t* lastcw0, uint8_t* lastcw1)
6197 #define ECMINFO_TYPE_OSCAM 0
6198 #define ECMINFO_TYPE_OSCAM_MS 1
6199 #define ECMINFO_TYPE_WICARDD 2
6200 #define ECMINFO_TYPE_MGCAMD 3
6201 #define ECMINFO_TYPE_CCCAM 4
6202 #define ECMINFO_TYPE_CAMD3 5
6204 FILE *ecmtxt = fopen(ECMINFO_FILE, "w");
6205 if(ecmtxt != NULL && er->rc < E_NOTFOUND)
6207 char tmp[25];
6208 const char *reader_name = NULL, *from_name = NULL, *proto_name = NULL;
6209 int8_t hops = 0;
6210 int32_t from_port = 0;
6211 char system_name[64];
6212 const char* const_system_name = get_cardsystem_desc_by_caid(er->caid);
6214 cs_strncpy(system_name, const_system_name, sizeof(system_name));
6215 system_name[0] = (char)toupper((int)system_name[0]);
6217 if(cfg.dvbapi_ecminfo_type <= ECMINFO_TYPE_WICARDD)
6219 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_WICARDD)
6221 fprintf(ecmtxt, "system: %s\n", system_name);
6224 fprintf(ecmtxt, "caid: 0x%04X\npid: 0x%04X\n", er->caid, er->pid);
6226 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_WICARDD)
6228 fprintf(ecmtxt, "prov: %06X\n", (uint) er->prid);
6230 else
6232 fprintf(ecmtxt, "prov: 0x%06X\n", (uint) er->prid);
6235 fprintf(ecmtxt, "chid: 0x%04X\n", er->chid);
6237 else if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_MGCAMD)
6239 fprintf(ecmtxt, "===== %s ECM on CaID 0x%04X, pid 0x%04X =====\nprov: %06X\n", system_name, er->caid, er->pid, (uint) er->prid);
6241 else if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_CCCAM)
6243 char provider_name[128];
6244 get_providername(er->prid, er->caid, provider_name, sizeof(provider_name));
6245 if(provider_name[0])
6247 fprintf(ecmtxt, "system: %s\ncaid: 0x%04X\nprovider: %s\nprovid: 0x%06X\npid: 0x%04X\n",
6248 system_name, er->caid, provider_name, (uint) er->prid, er->pid);
6250 else
6252 fprintf(ecmtxt, "system: %s\ncaid: 0x%04X\nprovid: 0x%06X\npid: 0x%04X\n", system_name, er->caid, (uint) er->prid, er->pid);
6255 else if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_CAMD3)
6257 fprintf(ecmtxt, "CAID 0x%04X, PID 0x%04X, PROVIDER 0x%06X\n", er->caid, er->pid, (uint) er->prid);
6260 switch(er->rc)
6262 case E_FOUND:
6263 if(er->selected_reader)
6265 reader_name = er->selected_reader->label;
6266 if(is_network_reader(er->selected_reader))
6267 { from_name = er->selected_reader->device; }
6268 else
6269 { from_name = "local"; }
6270 from_port = er->selected_reader->r_port;
6271 proto_name = reader_get_type_desc(er->selected_reader, 1);
6272 hops = er->selected_reader->currenthops;
6274 else
6276 reader_name = "none";
6277 from_name = "local";
6278 proto_name = "none";
6280 break;
6282 case E_CACHE1:
6283 reader_name = "Cache";
6284 from_name = "cache1";
6285 proto_name = "none";
6286 break;
6288 case E_CACHE2:
6289 reader_name = "Cache";
6290 from_name = "cache2";
6291 proto_name = "none";
6292 break;
6294 case E_CACHEEX:
6295 reader_name = "Cache";
6296 from_name = "cache3";
6297 proto_name = "none";
6298 break;
6302 if(cfg.dvbapi_ecminfo_type <= ECMINFO_TYPE_OSCAM_MS)
6304 switch(er->rc)
6306 case E_FOUND:
6307 if(er->selected_reader)
6309 fprintf(ecmtxt, "reader: %s\nfrom: %s\nprotocol: %s\nhops: %d\n", reader_name, from_name, proto_name, hops);
6311 break;
6313 case E_CACHE1:
6314 case E_CACHE2:
6315 case E_CACHEEX:
6316 fprintf(ecmtxt, "reader: %s\nfrom: %s\nprotocol: %s\n", reader_name, from_name, proto_name);
6317 break;
6320 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_OSCAM)
6321 { fprintf(ecmtxt, "ecm time: %.3f\n", (float) client->cwlastresptime / 1000); }
6322 else
6323 { fprintf(ecmtxt, "ecm time: %d\n", client->cwlastresptime); }
6326 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_CAMD3)
6328 fprintf(ecmtxt, "FROM: %s\n", reader_name);
6329 fprintf(ecmtxt, "CW0: %s\n", cs_hexdump(1, lastcw0, 8, tmp, sizeof(tmp)));
6330 fprintf(ecmtxt, "CW1: %s\n", cs_hexdump(1, lastcw1, 8, tmp, sizeof(tmp)));
6332 else
6334 fprintf(ecmtxt, "cw0: %s\n", cs_hexdump(1, lastcw0, 8, tmp, sizeof(tmp)));
6335 fprintf(ecmtxt, "cw1: %s\n", cs_hexdump(1, lastcw1, 8, tmp, sizeof(tmp)));
6338 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_WICARDD || cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_MGCAMD)
6340 time_t walltime;
6341 struct tm lt;
6342 char timebuf[32];
6344 fprintf(ecmtxt, "Signature %s\n", (isValidCW(lastcw0) || isValidCW(lastcw1)) ? "OK" : "NOK");
6346 if(reader_name != NULL)
6348 fprintf(ecmtxt, "source: %s (%s at %s:%d)\n", reader_name, proto_name, from_name, from_port);
6351 walltime = cs_time();
6352 localtime_r(&walltime, &lt);
6354 if(strftime(timebuf, 32, "%a %b %d %H:%M:%S %Y", &lt) != 0)
6356 fprintf(ecmtxt, "%d msec -- %s\n", client->cwlastresptime, timebuf);
6360 if(cfg.dvbapi_ecminfo_type == ECMINFO_TYPE_CCCAM)
6362 if(reader_name != NULL)
6364 fprintf(ecmtxt, "using: %s\naddress: %s:%d\nhops: %d\n", proto_name, from_name, from_port, hops);
6367 fprintf(ecmtxt, "ecm time: %d\n", client->cwlastresptime);
6371 if(ecmtxt)
6373 int32_t ret = fclose(ecmtxt);
6374 if(ret < 0) { cs_log("ERROR: Could not close ecmtxt fd (errno=%d %s)", errno, strerror(errno)); }
6375 ecmtxt = NULL;
6380 void *dvbapi_start_handler(struct s_client *cl, uchar *UNUSED(mbuf), int32_t module_idx, void * (*_main_func)(void *))
6382 // cs_log("dvbapi loaded fd=%d", idx);
6383 if(cfg.dvbapi_enabled == 1)
6385 cl = create_client(get_null_ip());
6386 cl->module_idx = module_idx;
6387 cl->typ = 'c';
6388 int32_t ret = start_thread("dvbapi handler", _main_func, (void *) cl, &cl->thread, 1, 0);
6389 if(ret)
6391 return NULL;
6395 return NULL;
6398 void *dvbapi_handler(struct s_client *cl, uchar *mbuf, int32_t module_idx)
6400 return dvbapi_start_handler(cl, mbuf, module_idx, dvbapi_main_local);
6403 int32_t dvbapi_set_section_filter(int32_t demux_index, ECM_REQUEST *er, int32_t n)
6405 if(!er) { return -1; }
6407 if(USE_OPENXCAS)
6409 return 0;
6412 if(selected_api != DVBAPI_3 && selected_api != DVBAPI_1 && selected_api != STAPI) // only valid for dvbapi3, dvbapi1 and STAPI
6414 return 0;
6417 if(cfg.dvbapi_boxtype == BOXTYPE_IPBOX || cfg.dvbapi_boxtype == BOXTYPE_IPBOX_PMT) // reported buggy using sectionfiltering after 1~4 hours -> for now disabled!
6419 return 0;
6422 if(n == -1)
6424 n = dvbapi_get_filternum(demux_index, er, TYPE_ECM);
6427 if(n < 0) { return -1; } // in case no valid filter found;
6429 int32_t fd = demux[demux_index].demux_fd[n].fd;
6430 if(fd < 1) { return -1 ; } // in case no valid fd
6432 uchar filter[16];
6433 uchar mask[16];
6434 memset(filter, 0, 16);
6435 memset(mask, 0, 16);
6437 struct s_ecmpids *curpid = NULL;
6438 int32_t pid = demux[demux_index].demux_fd[n].pidindex;
6439 if(pid != -1)
6441 curpid = &demux[demux_index].ECMpids[pid];
6443 if(curpid->table != er->ecm[0] && curpid->table != 0) { return -1; } // if current ecmtype differs from latest requested ecmtype do not apply section filtering!
6444 uint8_t ecmfilter = 0;
6446 if(er->ecm[0] == 0x80) { ecmfilter = 0x81; } // current processed ecm is even, next will be filtered for odd
6447 else { ecmfilter = 0x80; } // current processed ecm is odd, next will be filtered for even
6449 if(curpid->table != 0) // cycle ecmtype from odd to even or even to odd
6451 filter[0] = ecmfilter; // only accept new ecms (if previous odd, filter for even and visaversa)
6452 mask[0] = 0xFF;
6453 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set ecmtable to %s (CAID %04X PROVID %06X FD %d)", demux_index, n + 1,
6454 (ecmfilter == 0x80 ? "EVEN" : "ODD"), curpid->CAID, curpid->PROVID, fd);
6456 else // not decoding right now so we are interessted in all ecmtypes!
6458 filter[0] = 0x80; // set filter to wait for any ecms
6459 mask[0] = 0xF0;
6460 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set ecmtable to ODD+EVEN (CAID %04X PROVID %06X FD %d)", demux_index, n + 1,
6461 curpid->CAID, curpid->PROVID, fd);
6463 uint32_t offset = 0, extramask = 0xFF;
6465 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match(demux_index, pid, 'p');
6466 //cs_log("**** curpid->CHID %04X, checked = %d, er->chid = %04X *****", curpid->CHID, curpid->checked, er->chid);
6467 // checked 4 to make sure we dont set chid filter and no such ecm in dvbstream except for forced pids!
6468 if(curpid->CHID < 0x10000 && (curpid->checked == 4 || (forceentry && forceentry->force)))
6471 switch(er->caid >> 8)
6473 case 0x01:
6474 offset = 7;
6475 extramask = 0xF0;
6476 break; // seca
6477 case 0x05:
6478 offset = 8;
6479 break; // viaccess
6480 case 0x06:
6481 offset = 6;
6482 break; // irdeto
6483 case 0x09:
6484 offset = 11;
6485 break; // videoguard
6486 case 0x4A: // DRE-Crypt, Bulcrypt,Tongang and others?
6487 if(!caid_is_bulcrypt(er->caid))
6488 { offset = 6; }
6489 break;
6493 int32_t irdetomatch = 1; // check if wanted irdeto index is the one the delivers current chid!
6494 if(caid_is_irdeto(curpid->CAID))
6496 if(curpid->irdeto_curindex == er->ecm[4]) { irdetomatch = 1; } // ok apply chid filtering
6497 else { irdetomatch = 0; } // skip chid filtering but apply irdeto index filtering
6500 if(offset && irdetomatch) // we have a cas with chid or unique part in checked ecm
6502 i2b_buf(2, curpid->CHID, filter + (offset - 2));
6503 mask[(offset - 2)] = 0xFF&extramask; // additional mask seca2 chid can be FC10 or FD10 varies each month so only apply F?10
6504 mask[(offset - 1)] = 0xFF;
6505 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set chid to %04X on fd %d", demux_index, n + 1, curpid->CHID, fd);
6507 else
6509 if(caid_is_irdeto(curpid->CAID) && (curpid->irdeto_curindex < 0xFE)) // on irdeto we can always apply irdeto index filtering!
6511 filter[2] = curpid->irdeto_curindex;
6512 mask[2] = 0xFF;
6513 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set irdetoindex to %d on fd %d", demux_index, n + 1, curpid->irdeto_curindex, fd);
6515 else // all other cas systems also cas systems without chid or unique ecm part
6517 cs_log_dbg(D_DVBAPI, "Demuxer %d Filter %d set chid to ANY CHID on fd %d", demux_index, n + 1, fd);
6521 int32_t ret = dvbapi_activate_section_filter(demux_index, n, fd, curpid->ECM_PID, filter, mask);
6522 if(ret < 0) // something went wrong setting filter!
6524 cs_log("Demuxer %d Filter %d (fd %d) error setting section filtering -> stop filter!", demux_index, n + 1, fd);
6525 ret = dvbapi_stop_filternum(demux_index, n);
6526 if(ret == -1)
6528 cs_log("Demuxer %d Filter %d (fd %d) stopping filter failed -> kill all filters of this demuxer!", demux_index, n + 1, fd);
6529 dvbapi_stop_filter(demux_index, TYPE_EMM);
6530 dvbapi_stop_filter(demux_index, TYPE_ECM);
6532 return -1;
6534 return n;
6537 int32_t dvbapi_activate_section_filter(int32_t demux_index, int32_t num, int32_t fd, int32_t pid, uchar *filter, uchar *mask)
6540 int32_t ret = -1;
6542 switch(selected_api)
6544 case DVBAPI_3:
6546 struct dmx_sct_filter_params sFP2;
6547 memset(&sFP2, 0, sizeof(sFP2));
6548 sFP2.pid = pid;
6549 sFP2.timeout = 0;
6550 sFP2.flags = DMX_IMMEDIATE_START;
6551 if(cfg.dvbapi_boxtype == BOXTYPE_NEUMO)
6553 //DeepThought: on dgs/cubestation and neumo images, perhaps others
6554 //the following code is needed to descramble
6555 sFP2.filter.filter[0] = filter[0];
6556 sFP2.filter.mask[0] = mask[0];
6557 sFP2.filter.filter[1] = 0;
6558 sFP2.filter.mask[1] = 0;
6559 sFP2.filter.filter[2] = 0;
6560 sFP2.filter.mask[2] = 0;
6561 memcpy(sFP2.filter.filter + 3, filter + 1, 16 - 3);
6562 memcpy(sFP2.filter.mask + 3, mask + 1, 16 - 3);
6563 //DeepThought: in the drivers of the dgs/cubestation and neumo images,
6564 //dvbapi 1 and 3 are somehow mixed. In the kernel drivers, the DMX_SET_FILTER
6565 //ioctl expects to receive a dmx_sct_filter_params structure (DVBAPI 3) but
6566 //due to a bug its sets the "positive mask" wrongly (they should be all 0).
6567 //On the other hand, the DMX_SET_FILTER1 ioctl also uses the dmx_sct_filter_params
6568 //structure, which is incorrect (it should be dmxSctFilterParams).
6569 //The only way to get it right is to call DMX_SET_FILTER1 with the argument
6570 //expected by DMX_SET_FILTER. Otherwise, the timeout parameter is not passed correctly.
6571 ret = dvbapi_ioctl(fd, DMX_SET_FILTER1, &sFP2);
6573 else
6575 memcpy(sFP2.filter.filter, filter, 16);
6576 memcpy(sFP2.filter.mask, mask, 16);
6577 if (cfg.dvbapi_listenport || cfg.dvbapi_boxtype == BOXTYPE_PC_NODMX)
6578 ret = dvbapi_net_send(DVBAPI_DMX_SET_FILTER, demux[demux_index].socket_fd, demux_index, num, (unsigned char *) &sFP2, NULL, NULL, demux[demux_index].client_proto_version);
6579 else
6580 ret = dvbapi_ioctl(fd, DMX_SET_FILTER, &sFP2);
6582 break;
6585 case DVBAPI_1:
6587 struct dmxSctFilterParams sFP1;
6588 memset(&sFP1, 0, sizeof(sFP1));
6589 sFP1.pid = pid;
6590 sFP1.timeout = 0;
6591 sFP1.flags = DMX_IMMEDIATE_START;
6592 memcpy(sFP1.filter.filter, filter, 16);
6593 memcpy(sFP1.filter.mask, mask, 16);
6594 ret = dvbapi_ioctl(fd, DMX_SET_FILTER1, &sFP1);
6595 break;
6597 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
6598 case STAPI:
6600 ret = stapi_activate_section_filter(fd, filter, mask);
6601 break;
6603 #endif
6604 #if defined WITH_COOLAPI || defined WITH_COOLAPI2
6605 case COOLAPI:
6607 int32_t n = coolapi_get_filter_num(fd);
6608 if (n < 0)
6609 return n;
6610 coolapi_set_filter(fd, n, pid, filter, mask, TYPE_ECM);
6611 break;
6613 #endif
6615 default:
6616 break;
6618 if(ret!=-1) // only change filter/mask for comparing if box returned no errors!
6620 memcpy(demux[demux_index].demux_fd[num].filter, filter, 16); // copy filter to check later on if receiver delivered accordingly
6621 memcpy(demux[demux_index].demux_fd[num].mask, mask, 16); // copy mask to check later on if receiver delivered accordingly
6623 return ret;
6627 int32_t dvbapi_check_ecm_delayed_delivery(int32_t demux_index, ECM_REQUEST *er)
6629 int32_t ret = 0;
6630 int32_t filternum = dvbapi_get_filternum(demux_index, er, TYPE_ECM);
6631 char nullcw[CS_ECMSTORESIZE];
6632 memset(nullcw, 0, CS_ECMSTORESIZE);
6634 if(filternum < 0) { return 2; } // if no matching filter act like ecm response is delayed
6635 if(memcmp(demux[demux_index].demux_fd[filternum].lastecmd5, nullcw, CS_ECMSTORESIZE))
6637 demux[demux_index].demux_fd[filternum].lastresult = er->rc; // save last result
6638 char ecmd5[17 * 3];
6639 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
6640 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);
6641 unsigned char md5tmp[MD5_DIGEST_LENGTH];
6642 MD5(er->ecm, er->ecmlen, md5tmp);
6643 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!
6646 if(memcmp(er->cw, nullcw, 8) == 0 && memcmp(er->cw+8, nullcw, 8) == 0) {return 5;} // received a null cw -> not usable!
6647 struct s_ecmpids *curpid = NULL;
6649 int32_t pid = demux[demux_index].demux_fd[filternum].pidindex;
6651 if(pid !=-1)
6653 curpid = &demux[demux_index].ECMpids[pid];
6654 if(curpid->table == 0) { return 3; } // on change table act like ecm response is found
6657 if(er->rc == E_CACHEEX) { return 4; } // on cache-ex response act like ecm response is found
6660 return ret;
6663 int32_t dvbapi_get_filternum(int32_t demux_index, ECM_REQUEST *er, int32_t type)
6665 if(!er) { return -1; }
6667 int32_t n;
6668 int32_t fd = -1;
6670 for(n = 0; n < maxfilter; n++) // determine fd
6672 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)
6674 if(type == TYPE_ECM && er->srvid != demux[demux_index].program_number) continue;
6675 if((demux[demux_index].demux_fd[n].pid == er->pid) &&
6676 ((demux[demux_index].demux_fd[n].provid == er->prid) || demux[demux_index].demux_fd[n].provid == 0 || er->prid == 0) &&
6677 ((demux[demux_index].demux_fd[n].caid == er->caid) || (demux[demux_index].demux_fd[n].caid == er->ocaid))) // current ecm pid?
6679 fd = demux[demux_index].demux_fd[n].fd; // found!
6680 if(demux[demux_index].demux_fd[n].caid == er->ocaid)
6682 memset(demux[demux_index].demux_fd[n].lastecmd5, 0, CS_ECMSTORESIZE); // clear ecmd5 hash since betatunneled ecms hash different!
6684 break;
6688 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
6690 return (fd > 0 ? n : fd); // return -1(fd) on not found, on found return filternumber(n)
6693 ca_index_t dvbapi_ca_setpid(int32_t demux_index, int32_t pid, int32_t stream_id, bool use_des)
6695 ca_index_t idx;
6696 int32_t n;
6698 if(pid == -1 || pid > demux[demux_index].ECMpidcount) return INDEX_INVALID;
6700 if(demux[demux_index].ECMpids[pid].useMultipleIndices)
6702 n = stream_id;
6703 idx = demux[demux_index].ECMpids[pid].index[n];
6705 if(idx == INDEX_INVALID) // if no indexer for this pid get one!
6707 idx = dvbapi_get_descindex(demux_index, pid, n);
6708 if(idx == INDEX_INVALID)
6710 cs_log_dbg(D_DVBAPI, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X has no free index", demux_index, pid,
6711 demux[demux_index].ECMpids[pid].CAID, demux[demux_index].ECMpids[pid].ECM_PID);
6712 return INDEX_INVALID;
6715 cs_log_dbg(D_DVBAPI, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X is using index %d for stream %d", demux_index, pid,
6716 demux[demux_index].ECMpids[pid].CAID, demux[demux_index].ECMpids[pid].ECM_PID, idx, n);
6719 if(!demux[demux_index].ECMpids[pid].streams || ((demux[demux_index].ECMpids[pid].streams & (1 << n)) == (uint) (1 << n)))
6721 dvbapi_set_pid(demux_index, n, idx, true, use_des); // enable streampid
6723 else
6725 dvbapi_set_pid(demux_index, n, idx, false, false); // disable streampid
6728 else
6730 idx = demux[demux_index].ECMpids[pid].index[0];
6732 if(idx == INDEX_INVALID) // if no indexer for this pid get one!
6734 idx = dvbapi_get_descindex(demux_index, pid, 0);
6735 if(idx == INDEX_INVALID)
6737 cs_log_dbg(D_DVBAPI, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X has no free index", demux_index, pid,
6738 demux[demux_index].ECMpids[pid].CAID, demux[demux_index].ECMpids[pid].ECM_PID);
6739 return INDEX_INVALID;
6742 cs_log_dbg(D_DVBAPI, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X is using index %d", demux_index, pid,
6743 demux[demux_index].ECMpids[pid].CAID, demux[demux_index].ECMpids[pid].ECM_PID, idx);
6746 for(n = 0; n < demux[demux_index].STREAMpidcount; n++)
6748 if(!demux[demux_index].ECMpids[pid].streams || ((demux[demux_index].ECMpids[pid].streams & (1 << n)) == (uint) (1 << n)))
6750 dvbapi_set_pid(demux_index, n, idx, true, use_des); // enable streampid
6752 else
6754 dvbapi_set_pid(demux_index, n, idx, false, false); // disable streampid
6759 return idx; // return caindexer
6762 int8_t update_streampid_list(uint8_t cadevice, uint16_t pid, ca_index_t idx, bool use_des)
6764 struct s_streampid *listitem, *newlistitem;
6765 LL_ITER itr;
6767 if(!ll_activestreampids)
6768 { ll_activestreampids = ll_create("ll_activestreampids"); }
6770 if(idx > INDEX_MAX)
6771 { return INVALID_STREAMPID_INDEX; }
6773 if(ll_count(ll_activestreampids) > 0)
6775 itr = ll_iter_create(ll_activestreampids);
6776 while((listitem = ll_iter_next(&itr)))
6778 if (cadevice == listitem->cadevice && pid == listitem->streampid){
6779 if((listitem->activeindexers & (1 << idx)) == (uint64_t) (1 << idx)){
6781 if(cfg.dvbapi_extended_cw_api == 2 && use_des != listitem->use_des)
6783 listitem->use_des = use_des;
6784 return FIRST_STREAMPID_INDEX;
6787 return FOUND_STREAMPID_INDEX; // match found
6788 }else{
6789 listitem->activeindexers|=(1 << idx); // ca + pid found but not this index -> add this index
6790 cs_log_dbg(D_DVBAPI, "Added existing streampid %04X with new index %d to ca%d", pid, idx, cadevice);
6792 if(cfg.dvbapi_extended_cw_api == 2 && use_des != listitem->use_des)
6794 listitem->use_des = use_des;
6795 return FIRST_STREAMPID_INDEX;
6798 return ADDED_STREAMPID_INDEX;
6803 if(!cs_malloc(&newlistitem, sizeof(struct s_streampid)))
6804 { return FIRST_STREAMPID_INDEX; }
6805 newlistitem->cadevice = cadevice;
6806 newlistitem->streampid = pid;
6807 newlistitem->activeindexers = (1 << idx);
6808 newlistitem->caindex = idx; // set this index as used to decode on ca device
6809 newlistitem->use_des = use_des;
6810 ll_append(ll_activestreampids, newlistitem);
6811 cs_log_dbg(D_DVBAPI, "Added new streampid %04X with index %d to ca%d", pid, idx, cadevice);
6812 return FIRST_STREAMPID_INDEX;
6815 int8_t remove_streampid_from_list(uint8_t cadevice, uint16_t pid, ca_index_t idx)
6817 struct s_streampid *listitem;
6818 int8_t removed = 0;
6819 LL_ITER itr;
6821 if(!ll_activestreampids)
6822 { return NO_STREAMPID_LISTED; }
6824 if(idx > INDEX_MAX)
6825 { return INVALID_STREAMPID_INDEX; }
6827 if(ll_count(ll_activestreampids) > 0)
6829 itr = ll_iter_create(ll_activestreampids);
6830 while((listitem = ll_iter_next(&itr)))
6832 if (cadevice == listitem->cadevice && pid == listitem->streampid)
6834 if(idx == INDEX_DISABLE_ALL) {
6835 listitem->activeindexers = 0;
6836 removed = 1;
6838 else if((listitem->activeindexers & (1 << idx)) == (uint64_t) (1 << idx))
6840 listitem->activeindexers &= ~(1 << idx); // flag it as disabled for this index
6841 removed = 1;
6844 if(removed)
6846 cs_log_dbg(D_DVBAPI, "Remove streampid %04X using indexer %d from ca%d", pid, idx, cadevice);
6848 if (listitem->activeindexers == 0 && removed == 1) // all indexers disabled? -> remove pid from list!
6850 ll_iter_remove_data(&itr);
6851 cs_log_dbg(D_DVBAPI, "Removed last indexer of streampid %04X from ca%d", pid, cadevice);
6852 return REMOVED_STREAMPID_LASTINDEX;
6854 else if(removed == 1)
6856 if (idx != INDEX_DISABLE_ALL && idx != listitem->caindex)
6858 return REMOVED_STREAMPID_INDEX;
6860 else
6862 listitem->caindex = INDEX_INVALID;
6863 cs_log_dbg(D_DVBAPI, "Streampid %04X index %d was used for decoding on ca%d", pid, idx, cadevice);
6864 return REMOVED_DECODING_STREAMPID_INDEX;
6867 return INVALID_STREAMPID_INDEX;
6871 return NO_STREAMPID_LISTED;
6874 void disable_unused_streampids(int16_t demux_id)
6876 if(selected_api == STAPI) return; // stapi handles pids itself!
6878 if(!ll_activestreampids) return;
6879 if(ll_count(ll_activestreampids) == 0) return; // no items in list?
6881 int32_t ecmpid = demux[demux_id].pidindex;
6882 if (ecmpid == -1) return; // no active ecmpid!
6884 int32_t j;
6886 if(demux[demux_id].ECMpids[ecmpid].useMultipleIndices == 0)
6888 ca_index_t idx = demux[demux_id].ECMpids[ecmpid].index[0];
6889 int32_t i,n;
6890 struct s_streampid *listitem;
6891 // search for old enabled streampids on all ca devices that have to be disabled
6892 for(i = 0; i < MAX_DEMUX && idx != INDEX_INVALID; i++)
6894 if(!((demux[demux_id].ca_mask & (1 << i)) == (uint32_t) (1 << i))) continue; // continue if ca is unused by this demuxer
6896 LL_ITER itr;
6897 itr = ll_iter_create(ll_activestreampids);
6898 while((listitem = ll_iter_next(&itr)))
6900 if (i != listitem->cadevice) continue; // ca doesnt match
6901 if (!((listitem->activeindexers & (1 << (idx))) == (uint64_t) (1 << (idx)))) continue; // index doesnt match
6902 for(n = 0; n < demux[demux_id].STREAMpidcount; n++){
6903 if(demux[demux_id].ECMpidcount == 0) // FTA? -> disable stream!
6905 n = demux[demux_id].STREAMpidcount;
6906 break;
6908 if (listitem->streampid == demux[demux_id].STREAMpids[n]){ // check if pid matches with current streampid on demuxer
6909 break;
6912 if (n == demux[demux_id].STREAMpidcount){
6913 demux[demux_id].STREAMpids[n] = listitem->streampid; // put it temp here!
6914 dvbapi_set_pid(demux_id, n, idx, false, false); // no match found so disable this now unused streampid
6915 demux[demux_id].STREAMpids[n] = 0; // remove temp!
6919 for(n = 0; n < demux[demux_id].STREAMpidcount && demux[demux_id].ECMpidcount != 0; n++) // ECMpidcount != 0 -> skip enabling on fta
6921 ll_iter_reset(&itr);
6922 if(!demux[demux_id].ECMpids[ecmpid].streams || ((demux[demux_id].ECMpids[ecmpid].streams & (1 << n)) == (uint) (1 << n)))
6924 while((listitem = ll_iter_next(&itr)))
6926 if (i != listitem->cadevice) continue; // ca doesnt match
6927 if (!((listitem->activeindexers & (1 << (idx))) == (uint64_t) (1 << (idx)))) continue; // index doesnt match
6928 if (listitem->streampid == demux[demux_id].STREAMpids[n]) // check if pid matches with current streampid on demuxer
6930 break;
6933 if(!listitem) // if streampid not listed -> enable it!
6935 dvbapi_set_pid(demux_id, n, idx, true, false); // enable streampid
6941 else
6943 ca_index_t idx = INDEX_INVALID;
6944 int32_t i,n;
6945 uint8_t skip;
6946 struct s_streampid *listitem;
6947 // search for old enabled streampids on all ca devices that have to be disabled
6948 for(i = 0; i < MAX_DEMUX && idx != INDEX_INVALID; i++)
6950 if(!((demux[demux_id].ca_mask & (1 << i)) == (uint32_t) (1 << i))) continue; // continue if ca is unused by this demuxer
6952 LL_ITER itr;
6953 itr = ll_iter_create(ll_activestreampids);
6954 while((listitem = ll_iter_next(&itr)))
6956 if (i != listitem->cadevice) continue; // ca doesnt match
6958 for(skip = 1, j = 0; j < MAX_STREAM_INDICES; j++)
6960 idx = demux[demux_id].ECMpids[ecmpid].index[j];
6961 if(idx == INDEX_INVALID) continue;
6963 if ((listitem->activeindexers & (1 << (idx))) == (uint64_t) (1 << (idx)))
6965 skip = 0; // index match
6966 break;
6970 if(skip) continue;
6972 for(n = 0; n < demux[demux_id].STREAMpidcount; n++){
6973 if(demux[demux_id].ECMpidcount == 0) // FTA? -> disable stream!
6975 n = demux[demux_id].STREAMpidcount;
6976 break;
6978 if (listitem->streampid == demux[demux_id].STREAMpids[n]){ // check if pid matches with current streampid on demuxer
6979 break;
6982 if (n == demux[demux_id].STREAMpidcount){
6983 demux[demux_id].STREAMpids[n] = listitem->streampid; // put it temp here!
6984 dvbapi_set_pid(demux_id, n, idx, false, false); // no match found so disable this now unused streampid
6985 demux[demux_id].STREAMpids[n] = 0; // remove temp!
6989 for(n = 0; n < demux[demux_id].STREAMpidcount && demux[demux_id].ECMpidcount != 0; n++) // ECMpidcount != 0 -> skip enabling on fta
6991 ll_iter_reset(&itr);
6992 if(!demux[demux_id].ECMpids[ecmpid].streams || ((demux[demux_id].ECMpids[ecmpid].streams & (1 << n)) == (uint) (1 << n)))
6994 while((listitem = ll_iter_next(&itr)))
6996 if (i != listitem->cadevice) continue; // ca doesnt match
6998 for(skip = 1, j = 0; j < MAX_STREAM_INDICES; j++)
7000 idx = demux[demux_id].ECMpids[ecmpid].index[j];
7001 if(idx == INDEX_INVALID) continue;
7003 if ((listitem->activeindexers & (1 << (idx))) == (uint64_t) (1 << (idx)))
7005 skip = 0; // index match
7006 break;
7010 if(skip) continue;
7012 if (listitem->streampid == demux[demux_id].STREAMpids[n]) // check if pid matches with current streampid on demuxer
7014 break;
7017 if(!listitem) // if streampid not listed -> enable it!
7019 dvbapi_set_pid(demux_id, n, idx, true, false); // enable streampid
7028 ca_index_t is_ca_used(uint8_t cadevice, int32_t pid)
7030 struct s_streampid *listitem;
7031 LL_ITER itr;
7033 if(!ll_activestreampids)
7034 { return INDEX_INVALID; }
7036 if(ll_count(ll_activestreampids) > 0)
7038 itr = ll_iter_create(ll_activestreampids);
7039 while((listitem = ll_iter_next(&itr)))
7041 if(listitem->cadevice != cadevice)
7042 { continue; }
7044 if(pid && listitem->streampid != pid)
7045 { continue; }
7047 uint32_t i = 0;
7048 while(listitem->caindex == INDEX_INVALID && i <= INDEX_MAX)
7050 if((listitem->activeindexers&(1 << i)) == (uint64_t)(1 << i))
7052 listitem->caindex = i; // set fresh one
7053 cs_log_dbg(D_DVBAPI, "Streampid %04X is now using index %d for decoding on ca%d", pid, i, cadevice);
7054 break;
7056 i++;
7059 if(listitem->caindex == INDEX_INVALID)
7061 ll_iter_remove_data(&itr);
7062 return INDEX_INVALID;
7065 return listitem->caindex;
7068 return INDEX_INVALID; // no indexer found for this pid!
7071 uint16_t dvbapi_get_client_proto_version(void)
7073 return last_client_proto_version;
7076 const char *dvbapi_get_client_name(void)
7078 return last_client_name ? last_client_name : "";
7081 void check_add_emmpid(int32_t demux_index, uchar *filter, int32_t l, int32_t emmtype)
7083 if (l<0) return;
7085 uint32_t typtext_idx = 0;
7086 int32_t ret = -1;
7087 const char *typtext[] = { "UNIQUE", "SHARED", "GLOBAL", "UNKNOWN" };
7089 while(((emmtype >> typtext_idx) & 0x01) == 0 && typtext_idx < sizeof(typtext) / sizeof(const char *))
7091 ++typtext_idx;
7094 //filter already in list?
7095 if(is_emmfilter_in_list(filter, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].PROVID, demux[demux_index].EMMpids[l].CAID))
7097 cs_log_dbg(D_DVBAPI, "Demuxer %d duplicate emm filter type %s, emmpid: 0x%04X, emmcaid: %04X, emmprovid: %06X -> SKIPPED!", demux_index,
7098 typtext[typtext_idx], demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].CAID, demux[demux_index].EMMpids[l].PROVID);
7099 return;
7102 if(demux[demux_index].emm_filter < demux[demux_index].max_emm_filter) // can this filter be started?
7104 // try to activate this emmfilter
7105 ret = dvbapi_set_filter(demux_index, selected_api, demux[demux_index].EMMpids[l].PID, demux[demux_index].EMMpids[l].CAID,
7106 demux[demux_index].EMMpids[l].PROVID, filter, filter + 16, 0, demux[demux_index].pidindex, TYPE_EMM, 1);
7109 if(ret != -1) // -1 if maxfilter reached or filter start error!
7111 if(demux[demux_index].emm_filter == -1) // -1: first run of emm filtering on this demuxer
7113 demux[demux_index].emm_filter = 0;
7115 demux[demux_index].emm_filter++; // increase total active filters
7116 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);
7117 return;
7119 else // not set successful, so add it to the list for try again later on!
7121 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);
7122 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);
7124 return;
7127 void rotate_emmfilter(int32_t demux_id)
7129 // emm filter iteration
7130 if(!ll_emm_active_filter)
7131 { ll_emm_active_filter = ll_create("ll_emm_active_filter"); }
7133 if(!ll_emm_inactive_filter)
7134 { ll_emm_inactive_filter = ll_create("ll_emm_inactive_filter"); }
7136 if(!ll_emm_pending_filter)
7137 { ll_emm_pending_filter = ll_create("ll_emm_pending_filter"); }
7139 uint32_t filter_count = ll_count(ll_emm_active_filter) + ll_count(ll_emm_inactive_filter);
7141 if(demux[demux_id].max_emm_filter > 0
7142 && ll_count(ll_emm_inactive_filter) > 0
7143 && filter_count > demux[demux_id].max_emm_filter)
7146 int32_t filter_queue = ll_count(ll_emm_inactive_filter);
7147 int32_t stopped = 0, started = 0;
7148 struct timeb now;
7149 cs_ftime(&now);
7151 struct s_emm_filter *filter_item;
7152 LL_ITER itr;
7153 itr = ll_iter_create(ll_emm_active_filter);
7155 while((filter_item = ll_iter_next(&itr)) != NULL)
7157 if(!ll_count(ll_emm_inactive_filter) || started == filter_queue)
7158 { break; }
7159 int64_t gone = comp_timeb(&now, &filter_item->time_started);
7160 if( gone > 45*1000)
7162 struct s_dvbapi_priority *forceentry = dvbapi_check_prio_match_emmpid(filter_item->demux_id, filter_item->caid,
7163 filter_item->provid, 'p');
7165 if(!forceentry || (forceentry && !forceentry->force))
7167 // stop active filter and add to pending list
7168 dvbapi_stop_filternum(filter_item->demux_id, filter_item->num - 1);
7169 ll_iter_remove_data(&itr);
7170 add_emmfilter_to_list(filter_item->demux_id, filter_item->filter, filter_item->caid,
7171 filter_item->provid, filter_item->pid, -1, false);
7172 stopped++;
7176 int32_t ret;
7177 if(stopped > started) // we have room for new filters, try to start an inactive emmfilter!
7179 struct s_emm_filter *filter_item2;
7180 LL_ITER itr2 = ll_iter_create(ll_emm_inactive_filter);
7182 while((filter_item2 = ll_iter_next(&itr2)))
7184 ret = dvbapi_set_filter(filter_item2->demux_id, selected_api, filter_item2->pid, filter_item2->caid,
7185 filter_item2->provid, filter_item2->filter, filter_item2->filter + 16, 0,
7186 demux[filter_item2->demux_id].pidindex, TYPE_EMM, 1);
7187 if(ret != -1)
7189 ll_iter_remove_data(&itr2);
7190 started++;
7191 break;
7197 itr = ll_iter_create(ll_emm_pending_filter);
7199 while((filter_item = ll_iter_next(&itr)) != NULL) // move pending filters to inactive
7201 add_emmfilter_to_list(filter_item->demux_id, filter_item->filter, filter_item->caid, filter_item->provid, filter_item->pid, 0, false);
7202 ll_iter_remove_data(&itr);
7207 int32_t filtermatch(uchar *buffer, int32_t filter_num, int32_t demux_id, int32_t len)
7209 int32_t i, k, match;
7210 uint8_t flt, mask;
7211 match = 1;
7212 for(i = 0, k = 0; i < 16 && match; i++, k++)
7214 mask = demux[demux_id].demux_fd[filter_num].mask[i];
7215 if(k == 1) //skip len bytes
7217 k += 2;
7219 if(!mask)
7221 continue;
7223 flt = (demux[demux_id].demux_fd[filter_num].filter[i]&mask);
7224 //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,
7225 // demux[demux_id].demux_fd[filter_num].filter[i], i, mask, flt&mask, k, buffer[k], k, buffer[k] & mask);
7226 if(k <= len)
7228 match = (flt == (buffer[k] & mask));
7230 else
7232 match = 0;
7235 return (match && i == 16); // 0 = delivered data does not match with filter, 1 = delivered data matches with filter
7239 * protocol structure
7242 void module_dvbapi(struct s_module *ph)
7244 ph->desc = "dvbapi";
7245 ph->type = MOD_CONN_SERIAL;
7246 ph->listenertype = LIS_DVBAPI;
7247 #if defined(WITH_AZBOX)
7248 ph->s_handler = azbox_handler;
7249 ph->send_dcw = azbox_send_dcw;
7250 #elif defined(WITH_MCA)
7251 ph->s_handler = mca_handler;
7252 ph->send_dcw = mca_send_dcw;
7253 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
7254 #else
7255 ph->s_handler = dvbapi_handler;
7256 ph->send_dcw = dvbapi_send_dcw;
7257 #endif
7259 #endif // HAVE_DVBAPI