1 /* Reversed from libcoolstream.so, this comes without any warranty */
3 #define MODULE_LOG_PREFIX "dvbcool"
7 #if defined(HAVE_DVBAPI) && (defined(WITH_SU980) || defined(WITH_COOLAPI2) || defined(WITH_COOLAPI))
8 #include "extapi/coolapi.h"
10 #include "module-dvbapi.h"
11 #include "module-dvbapi-coolapi.h"
12 #include "oscam-string.h"
15 #define MAX_COOL_DMX 4
17 //kronos-Plattform (Coolsterem ZEE)
18 //#define MAX_COOL_DMX 3
21 #define DMX_MAX_FILTERS_PER_CHAN 16
22 #define DMX_MAX_CHANNELS_PER_DMX 192
23 //#define MAX_COOL_DMX_FILTERS 128
25 struct s_cool_chanhandle
;
27 typedef struct s_cool_filter
30 struct s_cool_chanhandle
*chanhandle
;
37 typedef struct s_cool_chanhandle
40 void *buffer1
; // filter Cbuf 1
41 void *buffer2
; // filter Cbuf 2
44 struct s_cool_dmxhandle
*dmx_handle
;
45 uint32_t allocated_filters
;
48 typedef struct s_cool_dmxhandle
51 uint32_t allocated_channels
;
59 pthread_mutex_t mutex
;
64 typedef struct cool_dmx dmx_t
;
96 int32_t unknown1
; // channel source
97 int32_t unknown2
; // mcard cap
98 int32_t unknown3
; // descrambler type
99 int32_t unknown4
; // support legacy NDS
108 uint8_t filter
[18]; //strange: initialization with max 18 possible but length limited to 12
120 CONTINUOUS_ACQUIRE
= 0,
134 } DATA_ACQUIRE_STATUS
;
145 DATA_ACQUIRE_STATUS type
;
151 DATA_ACQUIRE_MODE mode
;
154 void *filters
[DMX_MAX_FILTERS_PER_CHAN
];
155 void *tags
[DMX_MAX_FILTERS_PER_CHAN
];
156 } dmx_callback_data_t
;
158 /* These functions are implemented in libnxp */
159 extern int32_t cnxt_cbuf_open(void **handle
, buffer_open_arg_t
*arg
, void *, void *);
160 extern int32_t cnxt_dmx_open(void **device
, device_open_arg_t
*arg
, void *, void *);
161 extern int32_t cnxt_dmx_channel_open(void *device
, void **channel
, channel_open_arg_t
*arg
, void *callback
, void *);
162 extern int32_t cnxt_dmx_set_filter(void *handle
, filter_set_t
*arg
, void *);
163 extern int32_t cnxt_dmx_channel_suspend(void *handle
, int32_t enable
);
165 /* Local coolapi functions */
166 static int32_t coolapi_read(dmx_t
*dmx
, dmx_callback_data_t
*dataa
, uint8_t *buffer
);
168 static int8_t dmx_opened
;
169 int32_t cool_kal_opened
= 0;
171 static S_COOL_DMXHANDLE dmx_handles
[MAX_COOL_DMX
];
172 static dmx_t cdemuxes
[MAX_COOL_DMX
][MAX_FILTER
];
173 static pthread_mutex_t demux_lock
= PTHREAD_MUTEX_INITIALIZER
;
174 extern void *dvbapi_client
;
176 static LLIST
*ll_cool_filter
= NULL
;
177 static LLIST
*ll_cool_chanhandle
= NULL
;
179 #define COOLDEMUX_FD(device, num) (('O' << 24) | ('S' << 16) | (device << 8) | num)
180 #define COOLDEMUX_DMX_DEV(fd) (((fd) >> 8) & 0xFF)
181 #define COOLDEMUX_FLT_IDX(fd) (((fd) >> 0) & 0xFF)
182 #define COOLDEMUX_IS_VALID_FD(fd) ((((fd) & 0xFF000000) == ('O' << 24)) && \
183 (((fd) & 0x00FF0000) == ('S' << 16)))
185 #define COOLDEMUX_DATA_RECEIVED 1
186 #define COOLDEMUX_CHANNEL_TIMEOUT 2
187 #define COOLDEMUX_CRC_ERROR 3
188 #define COOLDEMUX_BUFF_OVERFLOW 4
190 static dmx_t
*find_demux(int32_t fd
, int32_t dmx_dev_num
)
192 if(dmx_dev_num
< 0 || dmx_dev_num
>= MAX_COOL_DMX
)
194 cs_log("Invalid demux %d", dmx_dev_num
);
201 if(fd
== 0) // DEMUX FILTER ALLOCATE
203 for(i
= 0; i
< MAX_FILTER
; i
++)
205 dmx
= &cdemuxes
[dmx_dev_num
][i
];
208 dmx
->fd
= COOLDEMUX_FD(dmx_dev_num
, i
);
209 cs_log_dbg(D_DVBAPI
, "opening new fd: %08x", dmx
->fd
);
213 cs_log_dbg(D_DVBAPI
, "ERROR: no free demux found");
217 if (!COOLDEMUX_IS_VALID_FD(fd
))
219 cs_log_dbg(D_DVBAPI
, "ERROR: invalid FD");
223 dmx_dev_num
= COOLDEMUX_DMX_DEV(fd
);
224 for(i
= 0; i
< MAX_FILTER
; i
++)
226 dmx
= &cdemuxes
[dmx_dev_num
][i
];
233 cs_log_dbg(D_DVBAPI
, "ERROR: CANT FIND Demux %08x", fd
);
238 int32_t coolapi_get_filter_num(int32_t fd
)
240 if (!COOLDEMUX_IS_VALID_FD(fd
))
242 cs_log_dbg(D_DVBAPI
, "ERROR: invalid FD");
246 return cdemuxes
[COOLDEMUX_DMX_DEV(fd
)][COOLDEMUX_FLT_IDX(fd
)].filter_num
;
249 static S_COOL_CHANHANDLE
*find_chanhandle(int32_t demux_index
, int32_t pid
)
251 // Find matching channel, if it exists.
252 if(ll_count(ll_cool_chanhandle
) > 0)
254 LL_ITER itr
= ll_iter_create(ll_cool_chanhandle
);
255 S_COOL_CHANHANDLE
*handle_item
;
257 while((handle_item
= ll_iter_next(&itr
)))
259 if(handle_item
->demux_index
== demux_index
&& handle_item
->pid
== pid
)
269 static int32_t remove_chanhandle(S_COOL_CHANHANDLE
*handle
)
271 // Find matching channel, if it exists.
272 if(ll_count(ll_cool_chanhandle
) > 0)
274 LL_ITER itr
= ll_iter_create(ll_cool_chanhandle
);
275 S_COOL_CHANHANDLE
*handle_item
;
277 while((handle_item
= ll_iter_next(&itr
)))
279 if(handle_item
== handle
)
281 ll_iter_remove_data(&itr
);
290 static S_COOL_FILTER
*find_filter_by_chanhandle(S_COOL_CHANHANDLE
*chanhandle
, int32_t filter_num
)
292 // Find matching channel, if it exists.
293 if(ll_count(ll_cool_filter
) > 0)
295 LL_ITER itr
= ll_iter_create(ll_cool_filter
);
296 S_COOL_FILTER
*filter_item
;
298 while((filter_item
= ll_iter_next(&itr
)))
300 if(filter_item
->chanhandle
== chanhandle
&& filter_item
->filter_num
== filter_num
)
310 static S_COOL_FILTER
*find_filter_by_channel(void *channel
, int32_t filter_num
)
312 // Find matching channel, if it exists.
313 if(ll_count(ll_cool_filter
) > 0)
315 LL_ITER itr
= ll_iter_create(ll_cool_filter
);
316 S_COOL_FILTER
*filter_item
;
318 while((filter_item
= ll_iter_next(&itr
)))
320 if(filter_item
->chanhandle
&&
321 filter_item
->chanhandle
->channel
== channel
&&
322 filter_item
->filter_num
== filter_num
)
332 static int32_t remove_filter(S_COOL_FILTER
*filter_handle
)
334 if(ll_count(ll_cool_filter
) > 0)
336 LL_ITER itr
= ll_iter_create(ll_cool_filter
);
337 S_COOL_FILTER
*filter_item
;
339 while((filter_item
= ll_iter_next(&itr
)))
341 if(filter_item
== filter_handle
)
343 ll_iter_remove_data(&itr
);
352 static void coolapi_read_data(dmx_t
*dmx
, dmx_callback_data_t
*data
)
356 cs_log_dbg(D_DVBAPI
, "handle is NULL!");
361 uint8_t buffer
[4096];
363 SAFE_SETSPECIFIC(getclient
, dvbapi_client
);
364 SAFE_MUTEX_LOCK(&dmx
->mutex
);
365 memset(buffer
, 0, sizeof(buffer
));
366 ret
= coolapi_read(dmx
, data
, buffer
);
367 SAFE_MUTEX_UNLOCK(&dmx
->mutex
);
370 uint16_t filters
= data
->num
;
373 for (flt
= 0; flt
< filters
; flt
++) {
374 uint32_t n
= (uint32_t)data
->tags
[flt
];
375 S_COOL_FILTER
*filter
= find_filter_by_channel(data
->channel
, n
);
377 if (!filter
|| data
->filters
[flt
] != filter
->filter
)
379 cs_log_dbg(D_DVBAPI
, "filter not found in notification!!!!");
383 dvbapi_process_input(dmx
->demux_id
, n
, buffer
, data
->len
, 0);
388 static void dmx_callback(void *channel
, dmx_t
*dmx
, int32_t type
, dmx_callback_data_t
*data
)
392 cs_log_dbg(D_DVBAPI
, "wrong dmx pointer !!!");
399 if (channel
!= data
->channel
)
409 if(data
->type
== COOLDEMUX_DATA_RECEIVED
&& data
->len
> 0) {
410 coolapi_read_data(dmx
, data
);
411 } else if(data
->type
== COOLDEMUX_CRC_ERROR
&& data
->len
> 0) {
412 cs_log_dbg(D_DVBAPI
, "CRC error !!!");
413 cnxt_cbuf_removed_data(data
->buf
, data
->len
);
414 } else if(data
->type
== COOLDEMUX_BUFF_OVERFLOW
) {
415 cs_log_dbg(D_DVBAPI
, "OVERFLOW !!!");
417 cs_log_dbg(D_DVBAPI
, "unknown callback data %d len %d", data
->type
, data
->len
);
425 int32_t coolapi_set_filter(int32_t fd
, int32_t num
, int32_t pid
, uint8_t *flt
, uint8_t *mask
, int32_t type
)
427 dmx_t
*dmx
= find_demux(fd
, 0);
430 cs_log_dbg(D_DVBAPI
, "dmx is NULL!");
434 int32_t result
, channel_found
;
435 SAFE_MUTEX_LOCK(&dmx
->mutex
);
437 // Find matching channel, if it exists.
438 S_COOL_CHANHANDLE
*handle_item
= find_chanhandle(COOLDEMUX_DMX_DEV(fd
), pid
);
441 // No channel was found, allocate one
442 buffer_open_arg_t bufarg
;
443 int32_t uBufferSize
= 8192 + 64;
444 /* Mark that we did not find any open channel on this PID */
447 if(!cs_malloc(&handle_item
, sizeof(S_COOL_CHANHANDLE
)))
452 memset(&bufarg
, 0, sizeof(bufarg
));
458 bufarg
.size
= uBufferSize
;
459 bufarg
.hwm
= (uBufferSize
* 7) / 8;
461 result
= cnxt_cbuf_open(&handle_item
->buffer1
, &bufarg
, NULL
, NULL
);
462 coolapi_check_error("cnxt_cbuf_open", result
);
468 result
= cnxt_cbuf_open(&handle_item
->buffer2
, &bufarg
, NULL
, NULL
);
469 coolapi_check_error("cnxt_cbuf_open", result
);
471 channel_open_arg_t chanarg
;
472 memset(&chanarg
, 0, sizeof(channel_open_arg_t
));
475 result
= cnxt_dmx_channel_open(dmx_handles
[COOLDEMUX_DMX_DEV(fd
)].handle
, &handle_item
->channel
, &chanarg
, dmx_callback
, dmx
);
476 coolapi_check_error("cnxt_dmx_channel_open", result
);
478 result
= cnxt_dmx_set_channel_buffer(handle_item
->channel
, 0, handle_item
->buffer1
);
479 coolapi_check_error("cnxt_dmx_set_channel_buffer", result
);
481 result
= cnxt_dmx_channel_attach(handle_item
->channel
, 0xB, 0, handle_item
->buffer2
);
482 coolapi_check_error("cnxt_dmx_channel_attach", result
);
484 result
= cnxt_cbuf_attach(handle_item
->buffer2
, 2, handle_item
->channel
);
485 coolapi_check_error("cnxt_cbuf_attach", result
);
487 result
= cnxt_dmx_set_channel_pid(handle_item
->channel
, pid
);
488 coolapi_check_error("cnxt_dmx_set_channel_pid", result
);
490 result
= cnxt_cbuf_flush(handle_item
->buffer1
, 0);
491 coolapi_check_error("cnxt_cbuf_flush", result
);
492 result
= cnxt_cbuf_flush(handle_item
->buffer2
, 0);
493 coolapi_check_error("cnxt_cbuf_flush", result
);
495 handle_item
->pid
= pid
;
496 handle_item
->dmx_handle
= &dmx_handles
[COOLDEMUX_DMX_DEV(fd
)];
497 dmx_handles
[COOLDEMUX_DMX_DEV(fd
)].allocated_channels
++;
498 ll_append(ll_cool_chanhandle
, handle_item
);
500 cs_log_dbg(D_DVBAPI
, "opened new channel %x", (int32_t) handle_item
->channel
);;
507 cs_log_dbg(D_DVBAPI
, "setting new filter fd=%08x demux=%d channel=%x num=%d pid=%04x flt=%x mask=%x", fd
, COOLDEMUX_DMX_DEV(fd
), (int32_t) handle_item
->channel
, num
, pid
, flt
[0], mask
[0]);
508 void *filter_handle
= NULL
;
509 filter_set_t filterset
;
510 int32_t has_filter
= 0;
512 S_COOL_FILTER
*filter_item
= find_filter_by_chanhandle(handle_item
, num
);
513 if (filter_item
&& type
== dmx
->type
&& pid
== dmx
->pid
&&
514 (memcmp(flt
, filter_item
->filter16
, 16) || memcmp(mask
, filter_item
->mask16
, 16)))
516 cs_log_dbg(D_DVBAPI
, "setting new filter fd=%08x demux=%d channel=%x num=%d pid=%04x flt=%x mask=%x, filter exists.. modifying", fd
, COOLDEMUX_DMX_DEV(fd
), (int32_t) handle_item
->channel
, num
, pid
, flt
[0], mask
[0]);
517 filter_handle
= filter_item
->filter
;
521 memcpy(filter_item
->filter16
, flt
, 16);
522 memcpy(filter_item
->mask16
, mask
, 16);
528 dmx
->filter_num
= num
;
529 result
= cnxt_dmx_open_filter(dmx_handles
[COOLDEMUX_DMX_DEV(fd
)].handle
, &filter_handle
);
530 coolapi_check_error("cnxt_dmx_open_filter", result
);
532 if(!cs_malloc(&filter_item
, sizeof(S_COOL_FILTER
)))
534 SAFE_MUTEX_UNLOCK(&dmx
->mutex
);
539 filter_item
->fd
= fd
;
540 filter_item
->filter
= filter_handle
;
541 filter_item
->filter_num
= num
;
542 filter_item
->chanhandle
= handle_item
;
543 memcpy(filter_item
->filter16
, flt
, 16);
544 memcpy(filter_item
->mask16
, mask
, 16);
547 ll_append(ll_cool_filter
, filter_item
);
548 // increase allocated filters
549 handle_item
->allocated_filters
++;
554 result
= cnxt_dmx_channel_suspend(handle_item
->channel
, 1);
555 coolapi_check_error("cnxt_dmx_channel_suspend", result
);
556 result
= cnxt_dmx_channel_detach_filter(handle_item
->channel
, filter_handle
);
557 coolapi_check_error("cnxt_dmx_channel_detach_filter", result
);
560 memset(&filterset
, 0, sizeof(filterset
));
561 filterset
.length
= 12;
562 memcpy(filterset
.filter
, flt
, 16);
563 memcpy(filterset
.mask
, mask
, 16);
565 result
= cnxt_dmx_set_filter(filter_handle
, &filterset
, (void *)num
);
566 coolapi_check_error("cnxt_dmx_set_filter", result
);
568 result
= cnxt_dmx_channel_attach_filter(handle_item
->channel
, filter_handle
);
569 coolapi_check_error("cnxt_dmx_channel_attach_filter", result
);
573 result
= cnxt_dmx_channel_suspend(handle_item
->channel
, 0);
574 coolapi_check_error("cnxt_dmx_channel_suspend", result
);
580 result
= cnxt_dmx_channel_ctrl(handle_item
->channel
, 2, 0);
581 coolapi_check_error("cnxt_dmx_channel_ctrl", result
);
584 SAFE_MUTEX_UNLOCK(&dmx
->mutex
);
589 int32_t coolapi_remove_filter(int32_t fd
, int32_t num
)
591 void * channel
= NULL
;
592 void * filter
= NULL
;
594 dmx_t
*dmx
= find_demux(fd
, 0);
597 cs_log_dbg(D_DVBAPI
, "dmx is NULL!");
606 SAFE_MUTEX_LOCK(&dmx
->mutex
);
608 // Find matching channel, if it exists.
609 S_COOL_CHANHANDLE
*handle_item
= find_chanhandle(COOLDEMUX_DMX_DEV(fd
), dmx
->pid
);
612 SAFE_MUTEX_UNLOCK(&dmx
->mutex
);
613 cs_log_dbg(D_DVBAPI
, "removing filter fd=%08x num=%d pid=%04xcfailed, channel does not exist.", fd
, num
, dmx
->pid
);
617 channel
= handle_item
->channel
;
618 cs_log_dbg(D_DVBAPI
, "removing filter fd=%08x num=%d pid=%04x on channel=%p", fd
, num
, dmx
->pid
, channel
);
621 S_COOL_FILTER
*filter_item
= find_filter_by_chanhandle(handle_item
, num
);
624 result
= cnxt_dmx_channel_suspend(channel
, 1);
625 coolapi_check_error("cnxt_dmx_channel_suspend", result
);
626 result
= cnxt_dmx_channel_detach_filter(channel
, filter_item
->filter
);
627 coolapi_check_error("cnxt_dmx_channel_detach_filter", result
);
629 result
= cnxt_dmx_close_filter(filter_item
->filter
);
630 coolapi_check_error("cnxt_dmx_close_filter", result
);
632 filter
= filter_item
->filter
;
633 remove_filter(filter_item
);
634 handle_item
->allocated_filters
--;
638 SAFE_MUTEX_UNLOCK(&dmx
->mutex
);
639 cs_log_dbg(D_DVBAPI
, "removing filter fd=%08x num=%d pid=%04x on channel=%x failed, channel does not exist.", fd
, num
, dmx
->pid
, (int32_t) handle_item
->channel
);
643 if (!handle_item
->allocated_filters
)
645 result
= cnxt_dmx_channel_ctrl(channel
, 0, 0);
646 coolapi_check_error("cnxt_dmx_channel_ctrl", result
);
647 cs_log_dbg(D_DVBAPI
, "closing channel %x", (int32_t) channel
);
649 result
= cnxt_dmx_set_channel_pid(channel
, 0x1FFF);
650 coolapi_check_error("cnxt_dmx_set_channel_pid", result
);
652 result
= cnxt_cbuf_flush(handle_item
->buffer1
, 0);
653 coolapi_check_error("cnxt_cbuf_flush", result
);
655 result
= cnxt_cbuf_flush(handle_item
->buffer2
, 0);
656 coolapi_check_error("cnxt_cbuf_flush", result
);
658 result
= cnxt_cbuf_detach(handle_item
->buffer2
, 2, channel
);
659 coolapi_check_error("cnxt_cbuf_detach", result
);
661 result
= cnxt_dmx_channel_detach(channel
, 0xB, 0, handle_item
->buffer1
);
662 coolapi_check_error("cnxt_dmx_channel_detach", result
);
665 result
= cnxt_dmx_channel_close(channel
);
666 coolapi_check_error("cnxt_dmx_channel_close", result
);
669 result
= cnxt_cbuf_close(handle_item
->buffer2
);
670 coolapi_check_error("cnxt_cbuf_close", result
);
672 result
= cnxt_cbuf_close(handle_item
->buffer1
);
673 coolapi_check_error("cnxt_cbuf_close", result
);
674 handle_item
->channel
= NULL
;
675 handle_item
->buffer1
= NULL
;
676 handle_item
->buffer2
= NULL
;
677 remove_chanhandle(handle_item
);
678 dmx_handles
[COOLDEMUX_DMX_DEV(fd
)].allocated_channels
--;
681 result
= cnxt_dmx_channel_suspend(channel
, 0);
682 coolapi_check_error("cnxt_dmx_channel_suspend", result
);
686 SAFE_MUTEX_UNLOCK(&dmx
->mutex
);
688 result
= cnxt_dmx_close_filter(filter
);
689 coolapi_check_error("cnxt_dmx_close_filter", result
);
692 // COOLAPI2 - We don't want to close Channel on no ECM Filters (Makes AU / EMMs work)
693 if(dmx
->type
!= TYPE_ECM
)
697 result
= cnxt_dmx_channel_close(channel
);
698 coolapi_check_error("cnxt_dmx_channel_close", result
);
704 int32_t coolapi_open_device(int32_t demux_index
, int32_t demux_id
)
708 SAFE_MUTEX_LOCK(&demux_lock
);
710 dmx
= find_demux(0, demux_index
);
713 SAFE_MUTEX_UNLOCK(&demux_lock
);
714 cs_log("no free demux found");
719 { ll_cool_filter
= ll_create("ll_cool_filter"); }
721 if(!ll_cool_chanhandle
)
722 { ll_cool_chanhandle
= ll_create("ll_cool_chanhandle"); }
724 dmx
->demux_id
= demux_id
;
727 //dmx->device = dmx_handles[demux_index].handle;
730 pthread_mutexattr_t attr
;
731 SAFE_MUTEXATTR_INIT(&attr
);
732 SAFE_MUTEXATTR_SETTYPE(&attr
, PTHREAD_MUTEX_ERRORCHECK_NP
);
733 SAFE_MUTEX_INIT(&dmx
->mutex
, &attr
);
735 SAFE_MUTEX_UNLOCK(&demux_lock
);
740 int32_t coolapi_close_device(int32_t fd
)
742 dmx_t
*dmx
= find_demux(fd
, 0);
745 cs_log_dbg(D_DVBAPI
, "dmx is NULL!");
746 SAFE_MUTEX_UNLOCK(&demux_lock
);
750 cs_log_dbg(D_DVBAPI
, "closing fd=%08x", fd
);
752 pthread_mutex_destroy(&dmx
->mutex
);
754 memset(dmx
, 0, sizeof(dmx_t
));
758 /* write cw to all demuxes in mask with passed index */
759 int32_t coolapi_write_cw(int32_t mask
, uint16_t *STREAMpids
, int32_t count
, ca_descr_t
*ca_descr
)
762 uint32_t idx
= ca_descr
->index
;
766 cs_log_dbg(D_DVBAPI
, "cw%d: mask %d index %d pid count %d", ca_descr
->parity
, mask
, idx
, count
);
767 for(i
= 0; i
< count
; i
++)
769 int32_t pid
= STREAMpids
[i
];
771 for(j
= 0; j
< MAX_COOL_DMX
; j
++)
775 result
= cnxt_dmx_get_channel_from_pid(dmx_handles
[j
].handle
, pid
, &channel
);
778 cs_log_dbg(D_DVBAPI
, "Found demux %d channel %x for pid %04x", j
, (int32_t) channel
, pid
);
779 result
= cnxt_dmx_set_channel_key(channel
, 0, ca_descr
->parity
, ca_descr
->cw
, 8);
780 coolapi_check_error("cnxt_dmx_set_channel_key", result
);
783 cs_log("set_channel_key failed for demux %d pid %04x", j
, pid
);
792 static int32_t coolapi_read(dmx_t
*dmx
, dmx_callback_data_t
*data
, uint8_t *buffer
)
796 cs_log_dbg(D_DVBAPI
, "dmx is NULL!");
801 uint32_t done
= 0, toread
, len
= data
->len
;
802 uint32_t bytes_used
= 0;
804 //cs_log_dbg(D_DVBAPI, "dmx channel %x pid %x len %d", (int) dmx->channel, dmx->pid, len);
806 result
= cnxt_cbuf_get_used(data
->buf
, &bytes_used
);
807 coolapi_check_error("cnxt_cbuf_get_used", result
);
811 result
= cnxt_cbuf_read_data(data
->buf
, buffer
, 3, &done
);
812 coolapi_check_error("cnxt_cbuf_read_data", result
);
817 toread
= ((buffer
[1] << 8) | buffer
[2]) & 0xFFF;
818 if((toread
+ 3) > len
)
820 result
= cnxt_cbuf_read_data(data
->buf
, buffer
+ 3, toread
, &done
);
821 coolapi_check_error("cnxt_cbuf_read_data", result
);
826 //cs_log_dbg(D_DVBAPI, "bytes read %d\n", done);
831 static void coolapi_dmx_open(void)
834 device_open_arg_t devarg
;
840 cs_log_dbg(D_DVBAPI
, "Open Coolstream DMX API");
842 memset(&devarg
, 0, sizeof(device_open_arg_t
));
847 for(i
= 0; i
< MAX_COOL_DMX
; i
++)
850 result
= cnxt_dmx_open(&dmx_handles
[i
].handle
, &devarg
, NULL
, NULL
);
851 coolapi_check_error("cnxt_dmx_open", result
);
857 static void coolapi_dmx_close(void)
864 for(i
= 0; i
< MAX_COOL_DMX
; i
++)
866 result
= cnxt_dmx_close(dmx_handles
[i
].handle
);
867 coolapi_check_error("cnxt_dmx_close", result
);
868 dmx_handles
[i
].handle
= NULL
;
874 static void coolapi_start_api(void);
875 static void coolapi_stop_api(void);
877 void coolapi_open_all(void)
879 SAFE_MUTEX_LOCK(&demux_lock
);
885 SAFE_MUTEX_UNLOCK(&demux_lock
);
888 void coolapi_close_all(void)
890 SAFE_MUTEX_LOCK(&demux_lock
);
893 SAFE_MUTEX_UNLOCK(&demux_lock
);
899 for(i
= 0; i
< MAX_COOL_DMX
; i
++)
901 for(j
= 0; j
< MAX_FILTER
; j
++)
903 if(cdemuxes
[i
][j
].fd
> 0)
905 coolapi_remove_filter(cdemuxes
[i
][j
].fd
, cdemuxes
[i
][j
].filter_num
);
906 coolapi_close_device(cdemuxes
[i
][j
].fd
);
915 SAFE_MUTEX_UNLOCK(&demux_lock
);
919 #if defined(HAVE_DVBAPI) && (defined(WITH_SU980) || defined(WITH_COOLAPI2))
920 #include "extapi/coolapi.h"
921 extern void cnxt_css_drv_init(void);
922 extern void cnxt_css_drv_term(void);
923 extern void cnxt_smc_term(void);
925 static void coolapi_start_api(void)
927 cnxt_kal_initialize();
929 cnxt_cbuf_init(NULL
);
934 static void coolapi_stop_api(void)
937 cnxt_kal_terminate();
939 #elif defined(HAVE_DVBAPI) && defined(WITH_COOLAPI)
940 static void coolapi_start_api(void)
942 cnxt_kal_initialize();
947 static void coolapi_stop_api(void)
949 cnxt_kal_terminate();