int32_t coolapi_remove_filter (int32_t fd, int32_t num) { int32_t result; dmx_t * dmx = find_demux(fd, 0); if(!dmx) { cs_debug_mask(D_DVBAPI, "dmx is NULL!"); return -1; } if(dmx->pid <= 0) return -1; cs_debug_mask(D_DVBAPI, "fd %08x channel %x num %d pid %x opened %s", fd, (int) dmx->channel, num, dmx->pid, dmx->opened ? "yes" : "no"); pthread_mutex_lock(&dmx->mutex); result = cnxt_dmx_channel_ctrl(dmx->channel, 0, 0); check_error ("cnxt_dmx_channel_ctrl", result); result = cnxt_dmx_set_channel_pid(dmx->channel, 0x1FFF); check_error ("cnxt_dmx_set_channel_pid", result); result = cnxt_cbuf_flush (dmx->buffer1, 0); check_error ("cnxt_cbuf_flush", result); result = cnxt_cbuf_flush (dmx->buffer2, 0); check_error ("cnxt_cbuf_flush", result); pthread_mutex_unlock(&dmx->mutex); dmx->pid = -1; return 0; }
int32_t coolapi_set_filter (int32_t fd, int32_t num, int32_t pid, unsigned char * flt, unsigned char * mask) { int32_t result; filter_set_t filter; dmx_t * dmx = find_demux(fd, 0); if(!dmx) { cs_debug_mask(D_DVBAPI, "dmx is NULL!"); return -1; } dmx->filter_num = num; cs_debug_mask(D_DVBAPI, "fd %08x demux %d channel %x num %d pid %x flt %x mask %x", fd, dmx->demux_index, (int) dmx->channel, num, pid, flt[0], mask[0]); memset(&filter, 0, sizeof(filter)); filter.length = 12; memcpy(filter.filter, flt, 12); memcpy(filter.mask, mask, 12); pthread_mutex_lock(&dmx->mutex); if(dmx->filter == NULL) { dmx->filter_attached = false; result = cnxt_dmx_open_filter(dmx->device, &dmx->filter); check_error ("cnxt_dmx_open_filter", result); } result = cnxt_dmx_set_filter(dmx->filter, &filter, NULL); check_error ("cnxt_dmx_set_filter", result); if(!dmx->filter_attached) { result = cnxt_dmx_channel_attach_filter(dmx->channel, dmx->filter); check_error ("cnxt_dmx_channel_attach_filter", result); } if(dmx->pid != pid) { result = cnxt_dmx_set_channel_pid(dmx->channel, pid); check_error ("cnxt_dmx_set_channel_pid", result); } result = cnxt_cbuf_flush (dmx->buffer1, 0); check_error ("cnxt_cbuf_flush", result); result = cnxt_cbuf_flush (dmx->buffer2, 0); check_error ("cnxt_cbuf_flush", result); result = cnxt_dmx_channel_ctrl(dmx->channel, 2, 0); check_error ("cnxt_dmx_channel_ctrl", result); dmx->pid = pid; pthread_mutex_unlock(&dmx->mutex); return 0; }
int32_t coolapi_remove_filter (int32_t fd, int32_t num) { dmx_t * dmx = find_demux(fd, 0); if(!dmx) { cs_debug_mask(D_DVBAPI, "dmx is NULL!"); return -1; } if(dmx->pid <= 0) return -1; int32_t result, filter_on_channel=0; cs_debug_mask(D_DVBAPI, "removing filter fd=%08x num=%d pid=%04x on channel=%x", fd, num, dmx->pid, (int32_t) dmx->channel); pthread_mutex_lock(&dmx->mutex); if(dmx->filter) { result = cnxt_dmx_channel_detach_filter(dmx->channel, dmx->filter); coolapi_check_error("cnxt_dmx_channel_detach_filter", result); result = cnxt_dmx_close_filter(dmx->filter); coolapi_check_error("cnxt_dmx_close_filter", result); dmx->filter = NULL; result = cnxt_dmx_channel_ctrl(dmx->channel, 0, 0); coolapi_check_error("cnxt_dmx_channel_ctrl", result); } LL_ITER itr = ll_iter_create(ll_cool_filter); S_COOL_FILTER *filter_item; while ((filter_item=ll_iter_next(&itr))) { if (filter_item->channel == (int32_t) dmx->channel) filter_on_channel++; if (filter_item->fd == fd) { ll_iter_remove_data(&itr); filter_on_channel--; } } if (!filter_on_channel) { cs_debug_mask(D_DVBAPI, "closing channel %x", (int32_t) dmx->channel); itr = ll_iter_create(ll_cool_chanhandle); S_COOL_CHANHANDLE *handle_item; while ((handle_item=ll_iter_next(&itr))) { if (handle_item->demux_index == dmx->demux_index && handle_item->pid == dmx->pid) { dmx->buffer1=handle_item->buffer1; dmx->buffer2=handle_item->buffer2; ll_iter_remove_data(&itr); break; } } if (!dmx->buffer1 || !dmx->buffer2) cs_debug_mask(D_DVBAPI, "WARNING: buffer handle not found!"); result = cnxt_dmx_channel_ctrl(dmx->channel, 0, 0); coolapi_check_error("cnxt_dmx_channel_ctrl", result); result = cnxt_dmx_set_channel_pid(dmx->channel, 0x1FFF); coolapi_check_error("cnxt_dmx_set_channel_pid", result); result = cnxt_cbuf_flush (dmx->buffer1, 0); coolapi_check_error("cnxt_cbuf_flush", result); result = cnxt_cbuf_flush (dmx->buffer2, 0); coolapi_check_error("cnxt_cbuf_flush", result); result = cnxt_cbuf_detach(dmx->buffer2, 2, dmx->channel); coolapi_check_error("cnxt_cbuf_detach", result); result = cnxt_dmx_channel_detach(dmx->channel, 0xB, 0, dmx->buffer1); coolapi_check_error("cnxt_dmx_channel_detach", result); result = cnxt_dmx_channel_close(dmx->channel); coolapi_check_error("cnxt_dmx_channel_close", result); result = cnxt_cbuf_close(dmx->buffer2); coolapi_check_error("cnxt_cbuf_close", result); result = cnxt_cbuf_close(dmx->buffer1); coolapi_check_error("cnxt_cbuf_close", result); } if (filter_on_channel) { result = cnxt_dmx_channel_ctrl(dmx->channel, 2, 0); coolapi_check_error("cnxt_dmx_channel_ctrl", result); } pthread_mutex_unlock(&dmx->mutex); dmx->pid = -1; return 0; }
int32_t coolapi_set_filter (int32_t fd, int32_t num, int32_t pid, uchar * flt, uchar * mask, int32_t type) { dmx_t * dmx = find_demux(fd, 0); if(!dmx) { cs_debug_mask(D_DVBAPI, "dmx is NULL!"); return -1; } int32_t result, channel_found=0; void * channel = NULL; if (ll_count(ll_cool_chanhandle) > 0) { LL_ITER itr = ll_iter_create(ll_cool_chanhandle); S_COOL_CHANHANDLE *handle_item; while ((handle_item=ll_iter_next(&itr))) { if (handle_item->demux_index == dmx->demux_index && handle_item->pid == pid) { channel = handle_item->channel; channel_found=1; break; } } } if (!channel) { buffer_open_arg_t bufarg; int32_t uBufferSize = 8256; memset(&bufarg, 0, sizeof(bufarg)); bufarg.type = 3; bufarg.size = uBufferSize; bufarg.unknown3 = (uBufferSize * 7) / 8; result = cnxt_cbuf_open(&dmx->buffer1, &bufarg, NULL, NULL); coolapi_check_error("cnxt_cbuf_open", result); bufarg.type = 0; result = cnxt_cbuf_open(&dmx->buffer2, &bufarg, NULL, NULL); coolapi_check_error("cnxt_cbuf_open", result); channel_open_arg_t chanarg; memset(&chanarg, 0, sizeof(channel_open_arg_t)); chanarg.type = 4; result = cnxt_dmx_channel_open(dmx->device, &dmx->channel, &chanarg, dmx_callback, dmx); coolapi_check_error("cnxt_dmx_channel_open", result); result = cnxt_dmx_set_channel_buffer(dmx->channel, 0, dmx->buffer1); coolapi_check_error("cnxt_dmx_set_channel_buffer", result); result = cnxt_dmx_channel_attach(dmx->channel, 0xB, 0, dmx->buffer2); coolapi_check_error("cnxt_dmx_channel_attach", result); result = cnxt_cbuf_attach(dmx->buffer2, 2, dmx->channel); coolapi_check_error("cnxt_cbuf_attach", result); result = cnxt_dmx_set_channel_pid(dmx->channel, pid); coolapi_check_error("cnxt_dmx_set_channel_pid", result); result = cnxt_cbuf_flush (dmx->buffer1, 0); coolapi_check_error("cnxt_cbuf_flush", result); result = cnxt_cbuf_flush (dmx->buffer2, 0); coolapi_check_error("cnxt_cbuf_flush", result); S_COOL_CHANHANDLE *handle_item; if (cs_malloc(&handle_item,sizeof(S_COOL_CHANHANDLE))) { handle_item->pid = pid; handle_item->channel = dmx->channel; handle_item->buffer1 = dmx->buffer1; handle_item->buffer2 = dmx->buffer2; handle_item->demux_index = dmx->demux_index; ll_append(ll_cool_chanhandle, handle_item); } cs_debug_mask(D_DVBAPI, "opened new channel %x", (int32_t) dmx->channel); } else { channel_found=1; dmx->channel = channel; dmx->buffer1 = NULL; dmx->buffer2 = NULL; } cs_debug_mask(D_DVBAPI, "setting new filter fd=%08x demux=%d channel=%x num=%d pid=%04x flt=%x mask=%x", fd, dmx->demux_index, (int32_t) dmx->channel, num, pid, flt[0], mask[0]); pthread_mutex_lock(&dmx->mutex); filter_set_t filter; dmx->filter_num = num; dmx->pid = pid; dmx->type = type; memset(&filter, 0, sizeof(filter)); filter.length = 12; memcpy(filter.filter, flt, 16); memcpy(filter.mask, mask, 16); result = cnxt_dmx_open_filter(dmx->device, &dmx->filter); coolapi_check_error("cnxt_dmx_open_filter", result); result = cnxt_dmx_set_filter(dmx->filter, &filter, NULL); coolapi_check_error("cnxt_dmx_set_filter", result); result = cnxt_dmx_channel_attach_filter(dmx->channel, dmx->filter); coolapi_check_error("cnxt_dmx_channel_attach_filter", result); if (channel_found) { result = cnxt_dmx_channel_ctrl(dmx->channel, 0, 0); coolapi_check_error("cnxt_dmx_channel_ctrl", result); } result = cnxt_dmx_channel_ctrl(dmx->channel, 2, 0); coolapi_check_error("cnxt_dmx_channel_ctrl", result); pthread_mutex_unlock(&dmx->mutex); S_COOL_FILTER *filter_item; if (cs_malloc(&filter_item,sizeof(S_COOL_FILTER))) { // fill filter item filter_item->fd = fd; filter_item->pid = pid; filter_item->channel = (int32_t) dmx->channel; memcpy(filter_item->filter16, flt, 16); memcpy(filter_item->mask16, mask, 16); //add filter item ll_append(ll_cool_filter, filter_item); } return 0; }
int32_t coolapi_remove_filter(int32_t fd, int32_t num) { void * channel = NULL; void * filter = NULL; dmx_t *dmx = find_demux(fd, 0); if(!dmx) { cs_log_dbg(D_DVBAPI, "dmx is NULL!"); return -1; } if(dmx->pid <= 0) { return -1; } int32_t result; SAFE_MUTEX_LOCK(&dmx->mutex); // Find matching channel, if it exists. S_COOL_CHANHANDLE *handle_item = find_chanhandle(COOLDEMUX_DMX_DEV(fd), dmx->pid); if (!handle_item) { SAFE_MUTEX_UNLOCK(&dmx->mutex); cs_log_dbg(D_DVBAPI, "removing filter fd=%08x num=%d pid=%04xcfailed, channel does not exist.", fd, num, dmx->pid); return -1; } channel = handle_item->channel; cs_log_dbg(D_DVBAPI, "removing filter fd=%08x num=%d pid=%04x on channel=%p", fd, num, dmx->pid, channel); S_COOL_FILTER *filter_item = find_filter_by_chanhandle(handle_item, num); if(filter_item) { result = cnxt_dmx_channel_suspend(channel, 1); coolapi_check_error("cnxt_dmx_channel_suspend", result); result = cnxt_dmx_channel_detach_filter(channel, filter_item->filter); coolapi_check_error("cnxt_dmx_channel_detach_filter", result); #if 0 result = cnxt_dmx_close_filter(filter_item->filter); coolapi_check_error("cnxt_dmx_close_filter", result); #endif filter = filter_item->filter; remove_filter(filter_item); handle_item->allocated_filters--; } else { SAFE_MUTEX_UNLOCK(&dmx->mutex); 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); return -1; } if (!handle_item->allocated_filters) { result = cnxt_dmx_channel_ctrl(channel, 0, 0); coolapi_check_error("cnxt_dmx_channel_ctrl", result); cs_log_dbg(D_DVBAPI, "closing channel %x", (int32_t) channel); result = cnxt_dmx_set_channel_pid(channel, 0x1FFF); coolapi_check_error("cnxt_dmx_set_channel_pid", result); result = cnxt_cbuf_flush(handle_item->buffer1, 0); coolapi_check_error("cnxt_cbuf_flush", result); result = cnxt_cbuf_flush(handle_item->buffer2, 0); coolapi_check_error("cnxt_cbuf_flush", result); result = cnxt_cbuf_detach(handle_item->buffer2, 2, channel); coolapi_check_error("cnxt_cbuf_detach", result); result = cnxt_dmx_channel_detach(channel, 0xB, 0, handle_item->buffer1); coolapi_check_error("cnxt_dmx_channel_detach", result); #if 0 result = cnxt_dmx_channel_close(channel); coolapi_check_error("cnxt_dmx_channel_close", result); #endif result = cnxt_cbuf_close(handle_item->buffer2); coolapi_check_error("cnxt_cbuf_close", result); result = cnxt_cbuf_close(handle_item->buffer1); coolapi_check_error("cnxt_cbuf_close", result); handle_item->channel = NULL; handle_item->buffer1 = NULL; handle_item->buffer2 = NULL; remove_chanhandle(handle_item); dmx_handles[COOLDEMUX_DMX_DEV(fd)].allocated_channels--; dmx->pid = -1; } else { result = cnxt_dmx_channel_suspend(channel, 0); coolapi_check_error("cnxt_dmx_channel_suspend", result); channel = NULL; } SAFE_MUTEX_UNLOCK(&dmx->mutex); if (filter) { result = cnxt_dmx_close_filter(filter); coolapi_check_error("cnxt_dmx_close_filter", result); } if (channel) { result = cnxt_dmx_channel_close(channel); coolapi_check_error("cnxt_dmx_channel_close", result); } return 0; }
int32_t coolapi_set_filter(int32_t fd, int32_t num, int32_t pid, uchar *flt, uchar *mask, int32_t type) { dmx_t *dmx = find_demux(fd, 0); if(!dmx) { cs_log_dbg(D_DVBAPI, "dmx is NULL!"); return -1; } int32_t result, channel_found; SAFE_MUTEX_LOCK(&dmx->mutex); // Find matching channel, if it exists. S_COOL_CHANHANDLE *handle_item = find_chanhandle(COOLDEMUX_DMX_DEV(fd), pid); if(!handle_item) { // No channel was found, allocate one buffer_open_arg_t bufarg; int32_t uBufferSize = 8192 + 64; /* Mark that we did not find any open channel on this PID */ channel_found = 0; if(!cs_malloc(&handle_item, sizeof(S_COOL_CHANHANDLE))) { return -1; } memset(&bufarg, 0, sizeof(bufarg)); #ifdef HAVE_COOLAPI2 bufarg.poolid = 5 #endif bufarg.type = 3; bufarg.size = uBufferSize; bufarg.hwm = (uBufferSize * 7) / 8; result = cnxt_cbuf_open(&handle_item->buffer1, &bufarg, NULL, NULL); coolapi_check_error("cnxt_cbuf_open", result); bufarg.type = 0; #ifdef HAVE_COOLAPI2 bufarg.poolid = 0 #endif result = cnxt_cbuf_open(&handle_item->buffer2, &bufarg, NULL, NULL); coolapi_check_error("cnxt_cbuf_open", result); channel_open_arg_t chanarg; memset(&chanarg, 0, sizeof(channel_open_arg_t)); chanarg.type = 4; result = cnxt_dmx_channel_open(dmx_handles[COOLDEMUX_DMX_DEV(fd)].handle, &handle_item->channel, &chanarg, dmx_callback, dmx); coolapi_check_error("cnxt_dmx_channel_open", result); result = cnxt_dmx_set_channel_buffer(handle_item->channel, 0, handle_item->buffer1); coolapi_check_error("cnxt_dmx_set_channel_buffer", result); result = cnxt_dmx_channel_attach(handle_item->channel, 0xB, 0, handle_item->buffer2); coolapi_check_error("cnxt_dmx_channel_attach", result); result = cnxt_cbuf_attach(handle_item->buffer2, 2, handle_item->channel); coolapi_check_error("cnxt_cbuf_attach", result); result = cnxt_dmx_set_channel_pid(handle_item->channel, pid); coolapi_check_error("cnxt_dmx_set_channel_pid", result); result = cnxt_cbuf_flush(handle_item->buffer1, 0); coolapi_check_error("cnxt_cbuf_flush", result); result = cnxt_cbuf_flush(handle_item->buffer2, 0); coolapi_check_error("cnxt_cbuf_flush", result); handle_item->pid = pid; handle_item->dmx_handle = &dmx_handles[COOLDEMUX_DMX_DEV(fd)]; dmx_handles[COOLDEMUX_DMX_DEV(fd)].allocated_channels++; ll_append(ll_cool_chanhandle, handle_item); cs_log_dbg(D_DVBAPI, "opened new channel %x", (int32_t) handle_item->channel);; } else { channel_found = 1; } 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]); void *filter_handle = NULL; filter_set_t filterset; int32_t has_filter = 0; S_COOL_FILTER *filter_item = find_filter_by_chanhandle(handle_item, num); if (filter_item && type == dmx->type && pid == dmx->pid && (memcmp(flt, filter_item->filter16, 16) || memcmp(mask, filter_item->mask16, 16))) { 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]); filter_handle = filter_item->filter; has_filter = 1; memcpy(filter_item->filter16, flt, 16); memcpy(filter_item->mask16, mask, 16); } else { dmx->pid = pid; dmx->type = type; dmx->filter_num = num; result = cnxt_dmx_open_filter(dmx_handles[COOLDEMUX_DMX_DEV(fd)].handle, &filter_handle); coolapi_check_error("cnxt_dmx_open_filter", result); if(!cs_malloc(&filter_item, sizeof(S_COOL_FILTER))) { SAFE_MUTEX_UNLOCK(&dmx->mutex); return -1; } // fill filter item filter_item->fd = fd; filter_item->filter = filter_handle; filter_item->filter_num = num; filter_item->chanhandle = handle_item; memcpy(filter_item->filter16, flt, 16); memcpy(filter_item->mask16, mask, 16); //add filter item ll_append(ll_cool_filter, filter_item); // increase allocated filters handle_item->allocated_filters++; } if (has_filter) { result = cnxt_dmx_channel_suspend(handle_item->channel, 1); coolapi_check_error("cnxt_dmx_channel_suspend", result); result = cnxt_dmx_channel_detach_filter(handle_item->channel, filter_handle); coolapi_check_error("cnxt_dmx_channel_detach_filter", result); } memset(&filterset, 0, sizeof(filterset)); filterset.length = 12; memcpy(filterset.filter, flt, 16); memcpy(filterset.mask, mask, 16); result = cnxt_dmx_set_filter(filter_handle, &filterset, (void *)num); coolapi_check_error("cnxt_dmx_set_filter", result); result = cnxt_dmx_channel_attach_filter(handle_item->channel, filter_handle); coolapi_check_error("cnxt_dmx_channel_attach_filter", result); if (has_filter) { result = cnxt_dmx_channel_suspend(handle_item->channel, 0); coolapi_check_error("cnxt_dmx_channel_suspend", result); } if(!channel_found) { // Start channel result = cnxt_dmx_channel_ctrl(handle_item->channel, 2, 0); coolapi_check_error("cnxt_dmx_channel_ctrl", result); } SAFE_MUTEX_UNLOCK(&dmx->mutex); return 0; }