1 #define MODULE_LOG_PREFIX "dvbstapi"
5 #if defined(HAVE_DVBAPI) && defined(WITH_STAPI5)
7 #include "module-dvbapi.h"
8 #include "module-dvbapi-stapi.h"
9 #include "oscam-client.h"
10 #include "oscam-files.h"
11 #include "oscam-string.h"
12 #include "oscam-time.h"
14 extern int32_t exit_oscam
;
16 #define MAX_STREAMPIDS MAX_DEMUX + 1
20 int STREAMPIDs
[MAX_STREAMPIDS
];
26 struct read_thread_param
33 #define PROCDIR "/proc/STAPI/stpti/"
34 #define MAX_DESCRAMBLER 16
35 #define TKD_MAX_NUMBER 1
37 /* These functions are in liboscam_stapi5.a */
38 extern char *oscam_stapi5_LibVersion(void);
39 extern uint32_t oscam_stapi5_Open(char *name
, uint32_t *sessionhandle
);
40 extern uint32_t oscam_stapi5_SignalAllocate(uint32_t sessionhandle
, uint32_t *signalhandle
);
41 extern uint32_t oscam_stapi5_FilterAllocate(uint32_t sessionhandle
, uint32_t *filterhandle
);
42 extern uint32_t oscam_stapi5_SlotInit(uint32_t sessionhandle
, uint32_t signalhandle
, uint32_t *bufferhandle
, uint32_t *slothandle
, uint16_t pid
);
43 extern uint32_t oscam_stapi5_FilterSet(uint32_t filterhandle
, uint8_t *filt
, uint8_t *mask
);
44 extern uint32_t oscam_stapi5_FilterAssociate(uint32_t filterhandle
, uint32_t slothandle
);
45 extern uint32_t oscam_stapi5_SlotDeallocate(uint32_t slothandle
);
46 extern uint32_t oscam_stapi5_BufferDeallocate(uint32_t bufferhandle
);
47 extern uint32_t oscam_stapi5_FilterDeallocate(uint32_t filterhandle
, uint32_t bufferhandle
, uint32_t slothandle
);
48 extern uint32_t oscam_stapi5_Close(uint32_t sessionhandle
);
49 extern const char *oscam_stapi5_GetRevision(void);
50 extern uint32_t oscam_stapi5_SignalWaitBuffer(uint32_t signalhandle
, uint32_t *qbuffer
, int32_t timeout
);
51 extern uint32_t oscam_stapi5_SignalDisassociateBuffer(uint32_t signalhandle
, uint32_t bufferhandle
);
52 extern uint32_t oscam_stapi5_BufferReadSection(uint32_t bufferhandle
, uint32_t *filterlist
, int32_t maxfilter
, uint32_t *filtercount
, int32_t *crc
, uint8_t *buf
, int32_t bufsize
, uint32_t *size
);
53 extern uint32_t oscam_stapi5_SignalAbort(uint32_t signalhandle
);
54 extern uint32_t oscam_stapi5_PidQuery(char *name
, uint16_t pid
);
55 extern uint32_t oscam_stapi5_BufferFlush(uint32_t bufferhandle
);
56 extern uint32_t oscam_stapi5_SlotClearPid(uint32_t slot
);
57 extern uint32_t oscam_stapi5_SlotUnlink(uint32_t slot
);
59 extern const char *oscam_sttkd_GetRevision(void);
60 extern uint32_t oscam_sttkd_Open(char *name
, uint32_t *sessionhandle
);
61 extern uint32_t oscam_sttkd_Close(uint32_t tkdhandle
);
62 extern uint32_t oscam_sttkd_Allocate(uint32_t tkdhandle
, uint8_t cp
, uint32_t *pathhandle
, uint32_t *keyhandle
);
63 extern uint32_t oscam_sttkd_Associate(char *name
, uint32_t pathhandle
, uint16_t Pid
);
64 extern uint32_t oscam_sttkd_Deallocate(uint32_t pathhandle
, uint32_t Keyhandle
);
65 extern uint32_t oscam_sttkd_Disassociate(char *name
, uint16_t pid
);
66 extern uint32_t oscam_sttkd_KeyWrite(uint32_t keyhandle
, uint8_t pol
, const uint8_t *cw
);
69 static void *stapi_read_thread(void *);
70 static int32_t stapi_do_set_filter(int32_t demux_id
, FILTERTYPE
*filter
, uint16_t *pids
, int32_t pidcount
, uint8_t *filt
, uint8_t *mask
, int32_t dev_id
);
71 static int32_t stapi_do_remove_filter(int32_t demux_id
, FILTERTYPE
*filter
, int32_t dev_id
);
73 // These variables are declared in module-dvbapi.c
74 extern int32_t disable_pmt_files
;
75 extern struct s_dvbapi_priority
*dvbapi_priority
;
76 extern DEMUXTYPE demux
[MAX_DEMUX
];
78 static int32_t stapi_on
;
79 static pthread_mutex_t filter_lock
;
80 struct STDEVICE dev_list
[PTINUM
];
82 struct tTkdDescInfo tkd_desc_info
[MAX_DESCRAMBLER
];
84 static char TKD_DeviceName
[TKD_MAX_NUMBER
][16];
85 static uint32_t TKDHandle
[TKD_MAX_NUMBER
];
88 static void stapi_off(void)
93 SAFE_MUTEX_LOCK(&filter_lock
);
95 cs_log("stapi shutdown");
97 disable_pmt_files
= 1;
99 for(i
= 0; i
< MAX_DESCRAMBLER
; i
++)
101 dvbapi_stop_descrambling(i
, 0);
103 if (tkd_desc_info
[i
].path_hndl
!= 0)
105 ErrorCode
= oscam_sttkd_Deallocate(tkd_desc_info
[i
].path_hndl
, tkd_desc_info
[i
].key_hndl
);
107 { cs_log("oscam_sttkd_Deallocate faild! ErrorCode: %d", ErrorCode
); }
111 uint8_t TKD_InstanceID
= 0;
112 for(TKD_InstanceID
= 0; TKD_InstanceID
< TKD_MAX_NUMBER
; TKD_InstanceID
++)
114 ErrorCode
= oscam_sttkd_Close(TKDHandle
[TKD_InstanceID
]);
116 { cs_log("oscam_sttkd_Close: ErrorCode: %d TKDHandle: 0x%08X", ErrorCode
, TKDHandle
[TKD_InstanceID
]); }
119 for(i
= 0; i
< PTINUM
; i
++)
121 if(dev_list
[i
].SessionHandle
> 0)
123 if(dev_list
[i
].SignalHandle
> 0)
125 oscam_stapi5_SignalAbort(dev_list
[i
].SignalHandle
);
127 pthread_cancel(dev_list
[i
].thread
);
131 SAFE_MUTEX_UNLOCK(&filter_lock
);
136 int32_t stapi_open(void)
141 struct dirent entry
, *dp
= NULL
;
146 int32_t stapi_priority
= 0;
148 dirp
= opendir(PROCDIR
);
151 cs_log("opendir failed (errno=%d %s)", errno
, strerror(errno
));
155 memset(dev_list
, 0, sizeof(struct STDEVICE
)*PTINUM
);
156 memset(pfad
, 0, sizeof(pfad
));
160 struct s_dvbapi_priority
*p
;
161 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
)
173 cs_log("WARNING: no PTI devices defined, stapi disabled");
177 oscam_stapi5_GetRevision();
178 oscam_sttkd_GetRevision();
181 while(!cs_readdir_r(dirp
, &entry
, &dp
))
185 snprintf(pfad
, sizeof(pfad
), "%s%s", PROCDIR
, dp
->d_name
);
186 if(stat(pfad
, &buf
) != 0)
189 if(!(buf
.st_mode
& S_IFDIR
&& strncmp(dp
->d_name
, ".", 1) != 0))
193 struct s_dvbapi_priority
*p
;
195 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
)
197 if(p
->type
!= 's') { continue; }
198 if(strcmp(dp
->d_name
, p
->devname
) == 0)
207 cs_log("PTI: %s skipped", dp
->d_name
);
211 ErrorCode
= oscam_stapi5_Open(dp
->d_name
, &dev_list
[i
].SessionHandle
);
214 cs_log("STPTI_Open ErrorCode: %d", ErrorCode
);
219 //oscam_stapi_Capability(dp->d_name);
221 cs_strncpy(dev_list
[i
].name
, dp
->d_name
, sizeof(dev_list
[i
].name
));
222 cs_log("PTI: %s open %d", dp
->d_name
, i
);
224 ErrorCode
= oscam_stapi5_SignalAllocate(dev_list
[i
].SessionHandle
, &dev_list
[i
].SignalHandle
);
226 { cs_log("SignalAllocate: ErrorCode: %d SignalHandle: %x", ErrorCode
, dev_list
[i
].SignalHandle
); }
229 if(i
>= PTINUM
) { break; }
233 if(i
== 0) { return 0; }
235 uint8_t TKD_InstanceID
= 0;
236 memset(&tkd_desc_info
, 0, sizeof(tkd_desc_info
[0]) * MAX_DESCRAMBLER
);
238 for(TKD_InstanceID
= 0; TKD_InstanceID
< TKD_MAX_NUMBER
; TKD_InstanceID
++)
240 /* Generate the device name dynamically based upon the Instance ID */
241 snprintf(TKD_DeviceName
[TKD_InstanceID
], sizeof(TKD_DeviceName
), "TKD_%02d", TKD_InstanceID
);
243 ErrorCode
= oscam_sttkd_Open(TKD_DeviceName
[TKD_InstanceID
], &TKDHandle
[TKD_InstanceID
]);
245 cs_log("oscam_sttkd_Open: DeviceName: %s, TKDHandle: 0x%08X, ErrorCode: %d", TKD_DeviceName
[TKD_InstanceID
], TKDHandle
[TKD_InstanceID
], ErrorCode
);
248 SAFE_MUTEX_INIT(&filter_lock
, NULL
);
250 for(i
= 0; i
< PTINUM
; i
++)
252 if(dev_list
[i
].SessionHandle
== 0)
255 struct read_thread_param
*para
;
256 if(!cs_malloc(¶
, sizeof(struct read_thread_param
)))
259 para
->cli
= cur_client();
261 int32_t ret
= start_thread("stapi read", stapi_read_thread
, (void *)para
, &dev_list
[i
].thread
, 1, 0);
270 cs_log("liboscam_stapi5 v.%s initialized", oscam_stapi5_LibVersion());
274 int32_t stapi_activate_section_filter(int32_t fd
, uint8_t *filter
, uint8_t *mask
)
278 ErrorCode
= oscam_stapi5_FilterSet(fd
, filter
, mask
);
281 cs_log_dbg(D_DVBAPI
, "Error: oscam_stapi5_FilterSet; %d", ErrorCode
);
288 int32_t stapi_set_filter(int32_t demux_id
, uint16_t pid
, uint8_t *filter
, uint8_t *mask
, int32_t num
, char *pmtfile
)
293 uint16_t pids
[1] = { pid
};
294 struct s_dvbapi_priority
*p
;
298 cs_log_dbg(D_DVBAPI
, "No valid pmtfile!");
302 cs_log_dbg(D_DVBAPI
, "pmt file %s demux_id %d", pmtfile
, demux_id
);
304 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
)
306 if(p
->type
!= 's') { continue; } // stapi rule?
307 if(strcmp(pmtfile
, p
->pmtfile
) != 0) { continue; } // same file?
309 for(i
= 0; i
< PTINUM
; i
++)
311 if(strcmp(dev_list
[i
].name
, p
->devname
) == 0 && p
->disablefilter
== 0) // check device name and if filtering is enabled!
313 cs_log_dbg(D_DVBAPI
, "set stapi filter on %s for pid %04X", dev_list
[i
].name
, pids
[0]);
314 ret
= stapi_do_set_filter(demux_id
, &dev_list
[i
].demux_fd
[demux_id
][num
], pids
, 1, filter
, mask
, i
);
315 if(ret
> 0) // success
317 demux
[demux_id
].dev_index
= i
;
318 cs_log_dbg(D_DVBAPI
, "%s filter %d set (pid %04X)", dev_list
[i
].name
, num
, pid
);
319 return ret
; // return filternumber
323 cs_log_dbg(D_DVBAPI
, "Error setting new filter for pid %04X on %s!", pid
, dev_list
[i
].name
);
324 return -1; // set return to error
332 cs_log_dbg(D_DVBAPI
, "No matching S: line in oscam.dvbapi for pmtfile %s -> stop descrambling!", pmtfile
);
333 snprintf(dest
, sizeof(dest
), "%s%s", TMPDIR
, demux
[demux_id
].pmt_file
);
334 unlink(dest
); // remove obsolete pmt file
335 dvbapi_stop_descrambling(demux_id
, 0);
340 int32_t stapi_remove_filter(int32_t demux_id
, int32_t num
, char *pmtfile
)
343 struct s_dvbapi_priority
*p
;
345 if(!pmtfile
) { return 0; }
347 for(p
= dvbapi_priority
; p
!= NULL
; p
= p
->next
)
349 if(p
->type
!= 's') { continue; }
350 if(strcmp(pmtfile
, p
->pmtfile
) != 0)
353 for(i
= 0; i
< PTINUM
; i
++)
355 if(strcmp(dev_list
[i
].name
, p
->devname
) == 0 && p
->disablefilter
== 0)
357 ret
= stapi_do_remove_filter(demux_id
, &dev_list
[i
].demux_fd
[demux_id
][num
], i
);
363 cs_log_dbg(D_DVBAPI
, "filter %d removed", num
);
367 cs_log_dbg(D_DVBAPI
, "Error: filter %d was not removed!", num
);
372 static uint32_t check_slot(int32_t dev_id
, uint32_t checkslot
, FILTERTYPE
*skipfilter
)
375 for(d
= 0; d
< MAX_DEMUX
; d
++)
377 for(f
= 0; f
< MAX_FILTER
; f
++)
379 if(skipfilter
&& &dev_list
[dev_id
].demux_fd
[d
][f
] == skipfilter
)
381 for(l
= 0; l
< dev_list
[dev_id
].demux_fd
[d
][f
].NumSlots
; l
++)
383 if(checkslot
== dev_list
[dev_id
].demux_fd
[d
][f
].SlotHandle
[l
])
385 return dev_list
[dev_id
].demux_fd
[d
][f
].BufferHandle
[l
];
394 static int32_t stapi_do_set_filter(int32_t demux_id
, FILTERTYPE
*filter
, uint16_t *pids
, int32_t pidcount
, uint8_t *filt
, uint8_t *mask
, int32_t dev_id
)
396 uint32_t FilterAssociateError
= 0;
400 filter
->BufferHandle
[0] = 0;
401 filter
->SlotHandle
[0] = 0;
403 if(dev_list
[dev_id
].SessionHandle
== 0) { return 0; }
405 uint32_t FilterAllocateError
= oscam_stapi5_FilterAllocate(dev_list
[dev_id
].SessionHandle
, &filter
->fd
);
407 if(FilterAllocateError
!= 0)
409 cs_log("FilterAllocate problem");
414 uint32_t FilterSetError
= oscam_stapi5_FilterSet(filter
->fd
, filt
, mask
);
416 for(k
= 0; k
< pidcount
; k
++)
418 uint16_t pid
= pids
[k
];
420 uint32_t QuerySlot
= oscam_stapi5_PidQuery(dev_list
[dev_id
].name
, pid
);
421 int32_t SlotInit
= 1;
425 uint32_t checkslot
= check_slot(dev_id
, QuerySlot
, NULL
);
428 filter
->SlotHandle
[k
] = QuerySlot
;
429 filter
->BufferHandle
[k
] = checkslot
;
434 cs_log("overtake: clear pid, errorcode: %d", oscam_stapi5_SlotClearPid(QuerySlot
));
441 ret
= oscam_stapi5_SlotInit(dev_list
[dev_id
].SessionHandle
, dev_list
[dev_id
].SignalHandle
, &filter
->BufferHandle
[k
], &filter
->SlotHandle
[k
], pid
);
444 FilterAssociateError
= oscam_stapi5_FilterAssociate(filter
->fd
, filter
->SlotHandle
[k
]);
448 if(ret
|| FilterAllocateError
|| FilterAssociateError
|| FilterSetError
)
450 cs_log("set_filter: dev: %d FAl: %d FAs: %d FS: %d",
451 dev_id
, FilterAllocateError
, FilterAssociateError
, FilterSetError
);
452 stapi_do_remove_filter(demux_id
, filter
, dev_id
);
457 return filter
->fd
; // return fd of filter
461 static int32_t stapi_do_remove_filter(int32_t UNUSED(demux_id
), FILTERTYPE
*filter
, int32_t dev_id
)
463 if(filter
->fd
== 0) { return 0; }
465 uint32_t BufferDeallocateError
= 0, SlotDeallocateError
= 0, FilterDeallocateError
= 0;
467 if(dev_list
[dev_id
].SessionHandle
== 0) { return 0; }
470 for(k
= 0; k
< filter
->NumSlots
; k
++)
472 uint32_t checkslot
= check_slot(dev_id
, filter
->SlotHandle
[k
], filter
);
476 FilterDeallocateError
= oscam_stapi5_FilterDeallocate(filter
->fd
, filter
->BufferHandle
[k
], filter
->SlotHandle
[k
]);
478 oscam_stapi5_SlotClearPid(filter
->SlotHandle
[k
]);
479 oscam_stapi5_SlotUnlink(filter
->SlotHandle
[k
]);
480 oscam_stapi5_SignalDisassociateBuffer(dev_list
[dev_id
].SignalHandle
, filter
->BufferHandle
[k
]);
482 BufferDeallocateError
= oscam_stapi5_BufferDeallocate(filter
->BufferHandle
[k
]);
483 SlotDeallocateError
= oscam_stapi5_SlotDeallocate(filter
->SlotHandle
[k
]);
488 memset(filter
, 0, sizeof(FILTERTYPE
));
490 if(BufferDeallocateError
|| SlotDeallocateError
|| FilterDeallocateError
)
492 cs_log("remove_filter: dev: %d BD: %d SD: %d FDe: %d",
493 dev_id
, BufferDeallocateError
, SlotDeallocateError
, FilterDeallocateError
);
502 static void stapi_cleanup_thread(void *dev
)
504 int32_t dev_index
= (int)dev
;
507 ErrorCode
= oscam_stapi5_Close(dev_list
[dev_index
].SessionHandle
);
509 cs_log("liboscam_stapi5: PTI %s closed - %d\n", dev_list
[dev_index
].name
, ErrorCode
);
510 dev_list
[dev_index
].SessionHandle
= 0;
513 static void *stapi_read_thread(void *sparam
)
515 int32_t dev_index
, ErrorCode
, i
, j
, CRCValid
;
516 uint32_t QueryBufferHandle
= 0, DataSize
= 0;
517 uint8_t buf
[BUFFLEN
];
519 struct read_thread_param
*para
= sparam
;
520 dev_index
= para
->id
;
522 SAFE_SETSPECIFIC(getclient
, para
->cli
);
523 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
);
524 pthread_cleanup_push(stapi_cleanup_thread
, (void *) dev_index
);
526 int32_t error_count
= 0;
530 QueryBufferHandle
= 0;
531 ErrorCode
= oscam_stapi5_SignalWaitBuffer(dev_list
[dev_index
].SignalHandle
, &QueryBufferHandle
, 1000);
537 case 852042: // ERROR_SIGNAL_ABORTED
538 cs_log("Caught abort signal");
541 case 11: // ERROR_TIMEOUT:
542 //cs_log("timeout %d", dev_index);
543 //TODO: if pidindex == -1 try next
547 if(QueryBufferHandle
!= 0)
549 cs_log("SignalWaitBuffer error: %d", ErrorCode
);
550 oscam_stapi5_BufferFlush(QueryBufferHandle
);
553 cs_log("SignalWaitBuffer: index %d ErrorCode: %d - QueryBuffer: %x", dev_index
, ErrorCode
, QueryBufferHandle
);
557 cs_log("Too many errors in reader thread %d, quitting.", dev_index
);
564 uint32_t NumFilterMatches
= 0;
565 int32_t demux_id
= 0, filter_num
= 0;
569 uint32_t MatchedFilterList
[10];
570 ErrorCode
= oscam_stapi5_BufferReadSection(QueryBufferHandle
, MatchedFilterList
, 10, &NumFilterMatches
, &CRCValid
, buf
, BUFFLEN
, &DataSize
);
574 cs_log("BufferRead: index: %d ErrorCode: %d", dev_index
, ErrorCode
);
582 SAFE_MUTEX_LOCK(&filter_lock
); // don't use cs_lock() here; multiple threads using same s_client struct
583 for(k
= 0; k
< NumFilterMatches
; k
++)
585 for(i
= 0; i
< MAX_DEMUX
; i
++)
587 for(j
= 0; j
< MAX_FILTER
; j
++)
589 if(dev_list
[dev_index
].demux_fd
[i
][j
].fd
== MatchedFilterList
[k
])
594 dvbapi_process_input(demux_id
, filter_num
, buf
, DataSize
, 0);
599 SAFE_MUTEX_UNLOCK(&filter_lock
);
602 pthread_cleanup_pop(0);
607 int32_t stapi_init_descrambler(int32_t dev_index
)
611 if(dev_index
>= MAX_DESCRAMBLER
)
613 cs_log("TKD MAX_DESCRAMBLER reached!");
617 ErrorCode
= oscam_sttkd_Allocate(TKDHandle
[0], 0, &tkd_desc_info
[dev_index
].path_hndl
, &tkd_desc_info
[dev_index
].key_hndl
);
620 cs_log("oscam_sttkd_Allocate faild! ErrorCode: %d", ErrorCode
);
627 int32_t stapi_set_pid(int32_t demux_id
, int32_t UNUSED(num
), uint32_t idx
, uint16_t pid
, char *UNUSED(pmtfile
))
629 if(idx
== INDEX_INVALID
)
631 if (tkd_desc_info
[demux
[demux_id
].dev_index
].path_hndl
!= 0)
633 cs_log_dbg(D_DVBAPI
, "stop descrambling of PID %d on %s", pid
, dev_list
[demux
[demux_id
].dev_index
].name
);
634 uint32_t ErrorCode
= oscam_sttkd_Disassociate(dev_list
[demux
[demux_id
].dev_index
].name
, pid
);
636 cs_log("oscam_sttkd_Disassociate faild! ErrorCode: %d", ErrorCode
);
639 for (i
= 0; i
< MAX_STREAMPIDS
; i
++)
641 if (tkd_desc_info
[demux
[demux_id
].dev_index
].STREAMPIDs
[i
] == pid
)
643 tkd_desc_info
[demux
[demux_id
].dev_index
].STREAMPIDs
[i
] = 0;
654 int32_t stapi_write_cw(int32_t demux_id
, uint8_t *cw
, uint16_t *STREAMpids
, int32_t STREAMpidcount
, char *UNUSED(pmtfile
))
656 int32_t ErrorCode
, l
, x
;
658 memset(nullcw
, 0, 8);
659 char *text
[] = { "even", "odd" };
661 if(dev_list
[demux
[demux_id
].dev_index
].SessionHandle
== 0) { return 0; }
663 // check if descrambler is started for this dev_index
664 if(tkd_desc_info
[demux
[demux_id
].dev_index
].path_hndl
== 0)
666 if(!stapi_init_descrambler(demux
[demux_id
].dev_index
))
668 cs_log_dbg(D_DVBAPI
, "stapi_write_cw , faild to added descrambler for %s", dev_list
[demux
[demux_id
].dev_index
].name
);
673 // descrambler started, check each pid
674 for (x
= 0; x
< STREAMpidcount
; x
++)
676 int pid_associated
= -1;
678 // search STREAMpids if path got associated
679 for (l
= 0; l
< MAX_STREAMPIDS
; l
++)
681 if (tkd_desc_info
[demux
[demux_id
].dev_index
].STREAMPIDs
[l
] == STREAMpids
[x
])
688 // if not associated add the pid
689 if(pid_associated
< 0)
691 ErrorCode
= oscam_sttkd_Associate(dev_list
[demux
[demux_id
].dev_index
].name
, tkd_desc_info
[demux
[demux_id
].dev_index
].path_hndl
, STREAMpids
[x
]);
694 cs_log("stapi_write_cw , oscam_sttkd_Associate faild for pid %04X! ErrorCode: %d", STREAMpids
[x
], ErrorCode
);
698 // add the pid to the next free index
699 for (l
= 0; l
< MAX_STREAMPIDS
; l
++)
701 if (tkd_desc_info
[demux
[demux_id
].dev_index
].STREAMPIDs
[l
] == 0)
703 tkd_desc_info
[demux
[demux_id
].dev_index
].STREAMPIDs
[l
] = STREAMpids
[x
];
709 if (pid_associated
< 0)
711 cs_log("stapi_write_cw , faild to associate pid %04X, maximum number of %d pids reached", STREAMpids
[x
], MAX_STREAMPIDS
);
717 //@theparasol: please verify this block is in the right place
718 int32_t pidnum
= demux
[demux_id
].pidindex
; // get current pidindex used for descrambling
719 uint32_t idx
= demux
[demux_id
].ECMpids
[pidnum
].index
[0];
721 if(idx
== INDEX_INVALID
) // if no indexer for this pid get one!
723 idx
= dvbapi_get_desc_index(demux_id
, pidnum
, 0);
724 cs_log_dbg(D_DVBAPI
, "Demuxer %d PID: %d CAID: %04X ECMPID: %04X is using index %d", demux_id
, pidnum
,
725 demux
[demux_id
].ECMpids
[pidnum
].CAID
, demux
[demux_id
].ECMpids
[pidnum
].ECM_PID
, idx
);
729 for(l
= 0; l
< 2; l
++)
731 // Skip check for BISS1 - cw could be indeed zero
732 // Skip check for BISS2 - we use the extended cw, so the "simple" cw is always zero
733 if(memcmp(cw
+ (l
* 8), demux
[demux_id
].last_cw
[0][l
], 8) != 0
734 && (memcmp(cw
+ (l
* 8), nullcw
, 8) != 0 || caid_is_biss(demux
[demux_id
].ECMpids
[pidnum
].CAID
)))
736 ErrorCode
= oscam_sttkd_KeyWrite(tkd_desc_info
[demux
[demux_id
].dev_index
].key_hndl
, l
, cw
+ (l
* 8));
738 memcpy(demux
[demux_id
].last_cw
[0][l
], cw
+ (l
* 8), 8);
739 cs_log_dbg(D_DVBAPI
, "write cw %s index: %d on %s", text
[l
], demux_id
, dev_list
[demux
[demux_id
].dev_index
].name
);