Ejemplo n.º 1
0
void coolapi_close_all(void)
{
	if(dmx_opened)
	{
		int32_t result;
		int32_t i, j;

		for(i = 0; i < MAX_COOL_DMX; i++)
		{
			for(j = 0; j < MAX_FILTER; j++)
			{
				if(cdemuxes[i][j].fd > 0)
				{
					coolapi_remove_filter(cdemuxes[i][j].fd, cdemuxes[i][j].filter_num);
					coolapi_close_device(cdemuxes[i][j].fd);
				}
			}
		}
		for(i = 0; i < MAX_COOL_DMX; i++)
		{
			result = cnxt_dmx_close(dmx_device[i]);
			coolapi_check_error("cnxt_dmx_close", result);
			dmx_device[i] = NULL;
		}
	}
	cool_kal_opened = 0;
	cnxt_kal_terminate();
	cnxt_drv_term();
}
Ejemplo n.º 2
0
static int32_t Cool_Init(struct s_reader *reader)
{
	char *device = reader->device;
	int32_t reader_nb = 0;
	// this is to stay compatible with older config.
	if(strlen(device))
		{ reader_nb = atoi((const char *)device); }
	if(reader_nb > 1)
	{
		// there are only 2 readers in the coolstream : 0 or 1
		rdr_log(reader, "Coolstream reader device can only be 0 or 1");
		return 0;
	}
	if(!cs_malloc(&reader->crdr_data, sizeof(struct cool_data)))
		{ return ERROR; }
	struct cool_data *crdr_data = reader->crdr_data;
	if(cnxt_smc_open(&crdr_data->handle, &reader_nb, NULL, NULL))
		{ return 0; }

	int32_t ret = cnxt_smc_enable_flow_control(crdr_data->handle, 0);
	coolapi_check_error("cnxt_smc_enable_flow_control", ret);

	crdr_data->cardbuflen = 0;
	crdr_data->pps = 0;
	return OK;
}
Ejemplo n.º 3
0
static int32_t Cool_Transmit(struct s_reader *reader, unsigned char *sent, uint32_t size, uint32_t expectedlen, uint32_t UNUSED(delay), uint32_t UNUSED(timeout))
{
	struct cool_data *crdr_data = reader->crdr_data;
	int32_t ret;
	memset(crdr_data->cardbuffer, 0, 512);

	if(reader->protocol_type == ATR_PROTOCOL_TYPE_T0)
	{
		crdr_data->cardbuflen = expectedlen;
		ret = cnxt_smc_read_write(crdr_data->handle, 0, sent, size, crdr_data->cardbuffer, &crdr_data->cardbuflen, 0, NULL);
	}
	else
	{
		crdr_data->cardbuflen = 512;
		ret = cnxt_smc_read_write(crdr_data->handle, 0, sent, size, crdr_data->cardbuffer, &crdr_data->cardbuflen, 4000, NULL);
	}

	coolapi_check_error("cnxt_smc_read_write", ret);

	rdr_log_dump_dbg(reader, D_DEVICE, sent, size, "COOL Transmit:");

	if(ret)
		{ return ERROR; }
	return OK;
}
Ejemplo n.º 4
0
int32_t Cool_WriteSettings (struct s_reader *reader, uint32_t UNUSED(BWT), uint32_t UNUSED(CWT), uint32_t UNUSED(EGT), uint32_t UNUSED(BGT))
{
	//this code worked with old cnxt_lnx.ko, but prevented nagra cards from working with new cnxt_lnx.ko
/*	struct
	{
		unsigned short  CardActTime;   //card activation time (in clock cycles = 1/54Mhz)
		unsigned short  CardDeactTime; //card deactivation time (in clock cycles = 1/54Mhz)
		unsigned short  ATRSTime;			//ATR first char timeout in clock cycles (1/f)
		unsigned short  ATRDTime;			//ATR duration in ETU
		unsigned long	  BWT;
		unsigned long   CWT;
		unsigned char   EGT;
		unsigned char   BGT;
	} params;
	params.BWT = BWT;
	params.CWT = CWT;
	params.EGT = EGT;
	params.BGT = BGT;
	call (cnxt_smc_set_config_timeout(specdev()->handle, params));
	rdr_debug_mask(reader, D_DEVICE, "COOL WriteSettings OK");*/

	//set freq back to reader->mhz if necessary
	uint32_t clk;
	int32_t ret = cnxt_smc_get_clock_freq (specdev()->handle, &clk);
	coolapi_check_error("cnxt_smc_get_clock_freq", ret);
	if (clk/10000 != (uint32_t)reader->mhz) {
		rdr_debug_mask(reader, D_DEVICE, "COOL: clock freq: %i, scheduling change to %i", clk, reader->mhz * 10000);
		call (Cool_SetClockrate(reader, reader->mhz));
	}

	return OK;
}
Ejemplo n.º 5
0
/* write cw to all demuxes in mask with passed index */
int32_t coolapi_write_cw(int32_t mask, uint16_t *STREAMpids, int32_t count, ca_descr_t *ca_descr)
{
	int32_t i, idx = ca_descr->index;
	int32_t result;
	void *channel;

	cs_log_dbg(D_DVBAPI, "cw%d: mask %d index %d pid count %d", ca_descr->parity, mask, idx, count);
	for(i = 0; i < count; i++)
	{
		int32_t pid = STREAMpids[i];
		int32_t j;
		for(j = 0; j < MAX_COOL_DMX; j++)
		{
			if(mask & (1 << j))
			{
				result = cnxt_dmx_get_channel_from_pid(dmx_handles[j].handle, pid, &channel);
				if(result == 0)
				{
					cs_log_dbg(D_DVBAPI, "Found demux %d channel %x for pid %04x", j, (int32_t) channel, pid);
					result = cnxt_dmx_set_channel_key(channel, 0, ca_descr->parity, ca_descr->cw, 8);
					coolapi_check_error("cnxt_dmx_set_channel_key", result);
					if(result != 0)
					{
						cs_log("set_channel_key failed for demux %d pid %04x", j, pid);
					}
				}
			}
		}
	}
	return 0;
}
Ejemplo n.º 6
0
static void coolapi_dmx_open(void)
{
	int32_t result = 0;
	device_open_arg_t devarg;

	if(!dmx_opened)
	{
		int32_t i;

		cs_log_dbg(D_DVBAPI, "Open Coolstream DMX API");

		memset(&devarg, 0, sizeof(device_open_arg_t));

		devarg.unknown1 = 1;
		devarg.unknown3 = 3;
		devarg.unknown6 = 1;
		for(i = 0; i < MAX_COOL_DMX; i++)
		{
			devarg.number = i;
			result = cnxt_dmx_open(&dmx_handles[i].handle, &devarg, NULL, NULL);
			coolapi_check_error("cnxt_dmx_open", result);
		}
		dmx_opened = 1;
	}
}
Ejemplo n.º 7
0
static int32_t Cool_Init (struct s_reader *reader)
{
	char *device = reader->device;
	int32_t reader_nb = 0;
	// this is to stay compatible with older config.
	if(strlen(device))
		reader_nb=atoi((const char *)device);
	if(reader_nb>1) {
		// there are only 2 readers in the coolstream : 0 or 1
		rdr_log(reader, "Coolstream reader device can only be 0 or 1");
		return 0;
	}
	if (!cs_malloc(&reader->spec_dev, sizeof(struct s_coolstream_reader)))
		return 0;
	if (cnxt_smc_open (&specdev()->handle, &reader_nb, NULL, NULL))
		return 0;

	int32_t ret = cnxt_smc_enable_flow_control(specdev()->handle, 1);
	coolapi_check_error("cnxt_smc_enable_flow_control", ret);

	specdev()->cardbuflen = 0;
	if (reader->cool_timeout_init > 0) {
		rdr_debug_mask(reader, D_DEVICE, "init timeout set to cool_timeout_init = %i", reader->cool_timeout_init);
		specdev()->read_write_transmit_timeout = reader->cool_timeout_init;
	} else {
		rdr_debug_mask(reader, D_DEVICE, "No init timeout specified - using value from ATR. If you encounter any problems while card init try to use the reader parameter cool_timeout_init = 500");
		specdev()->read_write_transmit_timeout = -1;
	}
	return OK;
}
Ejemplo n.º 8
0
void coolapi_open(void)
{
	int32_t result = 0;
	device_open_arg_t devarg;

    if(!dmx_opened) {
		int32_t i;

		cs_debug_mask(D_DVBAPI, "Open Coolstream DMX API");
		cnxt_cbuf_init(NULL);
		cnxt_dmx_init(NULL);

		memset(&devarg, 0, sizeof(device_open_arg_t));

		devarg.unknown1 = 1;
		devarg.unknown3 = 3;
		devarg.unknown6 = 1;
		for(i = 0; i < MAX_COOL_DMX; i++) {
		        devarg.number = i;
		        result = cnxt_dmx_open (&dmx_device[i], &devarg, NULL, NULL);
		        coolapi_check_error("cnxt_dmx_open", result);
		}
		dmx_opened = 1;
    }
}
Ejemplo n.º 9
0
int32_t Cool_FastReset_With_ATR (struct s_reader *reader, ATR * atr)
{
	int32_t n = 40, ret;
	unsigned char buf[40];

	//reset card
	ret = cnxt_smc_reset_card (specdev()->handle, ATR_TIMEOUT, NULL, NULL);
	coolapi_check_error("cnxt_smc_reset_card", ret);
	cs_sleepms(50);
	ret = cnxt_smc_get_atr (specdev()->handle, buf, &n);
	coolapi_check_error("cnxt_smc_get_atr", ret);

	call (!ATR_InitFromArray (atr, buf, n) == ATR_OK);
	{
		cs_sleepms(50);
		return OK;
	}
}
Ejemplo n.º 10
0
static int32_t Cool_Close (struct s_reader *reader)
{
	if (cool_kal_opened) {
		int32_t ret = cnxt_smc_close (specdev()->handle);
		coolapi_check_error("cnxt_smc_close", ret);
	}
	NULLFREE(reader->spec_dev);
	return OK;
}
Ejemplo n.º 11
0
static int32_t Cool_Close(struct s_reader *reader)
{
	struct cool_data *crdr_data = reader->crdr_data;
	if(cool_kal_opened)
	{
		int32_t ret = cnxt_smc_close(crdr_data->handle);
		coolapi_check_error("cnxt_smc_close", ret);
	}
	return OK;
}
Ejemplo n.º 12
0
static int32_t Cool_SetClockrate (struct s_reader *reader, int32_t mhz)
{
        uint32_t clk;
        clk = mhz * 10000;
        int32_t ret = cnxt_smc_set_clock_freq (specdev()->handle, clk);
        coolapi_check_error("cnxt_smc_set_clock_freq", ret);
        call (Cool_FastReset(reader));
        rdr_debug_mask(reader, D_DEVICE, "COOL: clock succesfully set to %i", clk);
        return OK;
}
Ejemplo n.º 13
0
int32_t Cool_Transmit (struct s_reader *reader, BYTE * sent, uint32_t size)
{
	specdev()->cardbuflen = 256;//it needs to know max buffer size to respond?

	int32_t ret = cnxt_smc_read_write(specdev()->handle, FALSE, sent, size, specdev()->cardbuffer, &specdev()->cardbuflen, specdev()->read_write_transmit_timeout, 0);
	coolapi_check_error("cnxt_smc_read_write", ret);

	rdr_ddump_mask(reader, D_DEVICE, sent, size, "COOL Transmit:");
	return OK;
}
Ejemplo n.º 14
0
static int32_t Cool_SetClockrate(struct s_reader *reader, int32_t mhz)
{
	struct cool_data *crdr_data = reader->crdr_data;
	uint32_t clk;
	clk = mhz * 10000;
	int32_t ret = cnxt_smc_set_clock_freq(crdr_data->handle, clk);
	coolapi_check_error("cnxt_smc_set_clock_freq", ret);
	call(Cool_FastReset(reader));
	rdr_log_dbg(reader, D_DEVICE, "COOL: clock succesfully set to %i", clk);
	return OK;
}
Ejemplo n.º 15
0
static int32_t Cool_Reset(struct s_reader *reader, ATR *atr)
{
	struct cool_data *crdr_data = reader->crdr_data;
	int32_t ret;

	if(!reader->ins7e11_fast_reset)
	{
		//set freq to reader->cardmhz if necessary
		uint32_t clk;

		ret = cnxt_smc_get_clock_freq(crdr_data->handle, &clk);
		coolapi_check_error("cnxt_smc_get_clock_freq", ret);
		if(clk / 10000 != (uint32_t)reader->cardmhz)
		{
			rdr_log_dbg(reader, D_DEVICE, "COOL: clock freq: %i, scheduling change to %i for card reset",
						   clk, reader->cardmhz * 10000);
			call(Cool_SetClockrate(reader, reader->cardmhz));
		}
	}
	else
	{
		rdr_log(reader, "Doing fast reset");
	}

	//reset card
	ret = cnxt_smc_reset_card(crdr_data->handle, ATR_TIMEOUT, NULL, NULL);
	coolapi_check_error("cnxt_smc_reset_card", ret);
	cs_sleepms(50);
	int32_t n = ATR_MAX_SIZE;
	unsigned char buf[ATR_MAX_SIZE];
	ret = cnxt_smc_get_atr(crdr_data->handle, buf, &n);
	coolapi_check_error("cnxt_smc_get_atr", ret);

	call(!ATR_InitFromArray(atr, buf, n) != ERROR);
	{
		cs_sleepms(50);
		return OK;
	}
}
Ejemplo n.º 16
0
int32_t coolapi_read(dmx_t *dmx, dmx_callback_data_t *data)
{
	if(!dmx)
	{
		cs_debug_mask(D_DVBAPI, "dmx is NULL!");
		return -1;
	}

	int32_t result;
	uint32_t done = 0, toread, len = data->len;
	uchar *buff = &dmx->buffer[0];
	uint32_t bytes_used = 0;

	//cs_debug_mask(D_DVBAPI, "dmx channel %x pid %x len %d",  (int) dmx->channel, dmx->pid, len);

	result = cnxt_cbuf_get_used(data->buf, &bytes_used);
	coolapi_check_error("cnxt_cbuf_get_used", result);
	if(bytes_used == 0)
		{ return -1; }

	result = cnxt_cbuf_read_data(data->buf, buff, 3, &done);
	coolapi_check_error("cnxt_cbuf_read_data", result);

	if(done != 3)
		{ return -1; }

	toread = ((buff[1] << 8) | buff[2]) & 0xFFF;
	if((toread + 3) > len)
		{ return -1; }
	result = cnxt_cbuf_read_data(data->buf, buff + 3, toread, &done);
	coolapi_check_error("cnxt_cbuf_read_data", result);
	if(done != toread)
		{ return -1; }
	done += 3;

	//cs_debug_mask(D_DVBAPI, "bytes read %d\n", done);

	return 0;
}
Ejemplo n.º 17
0
static int32_t Cool_WriteSettings (struct s_reader *reader, uint32_t UNUSED(BWT), uint32_t UNUSED(CWT), uint32_t UNUSED(EGT), uint32_t UNUSED(BGT))
{
	//first set freq back to reader->mhz if necessary
	uint32_t clk;
	int32_t ret = cnxt_smc_get_clock_freq (specdev()->handle, &clk);
	coolapi_check_error("cnxt_smc_get_clock_freq", ret);
	if (clk/10000 != (uint32_t)reader->mhz) {
		rdr_debug_mask(reader, D_DEVICE, "COOL: clock freq: %i, scheduling change to %i", clk, reader->mhz * 10000);
		call (Cool_SetClockrate(reader, reader->mhz));
	}

	//driver sets values in ETU automatically (except read_write_transmit_timeout)
	//... but lets see what the driver did
	uint16_t F;
	uint8_t D;
	ret = cnxt_smc_get_F_D_factors(specdev()->handle, &F, &D);
	coolapi_check_error("cnxt_smc_get_F_D_factors", ret);
	char *protocol;
	CNXT_SMC_COMM comm;
	ret = cnxt_smc_get_comm_parameters(specdev()->handle, &comm);
	coolapi_check_error("cnxt_smc_get_comm_parameters", ret);
	if (comm.protocol==0x01)
		protocol = "T0";
	else if (comm.protocol==0x02)
		protocol = "T1";
	else if (comm.protocol==0x04)
		protocol = "T14";
	else
		protocol = "unknown";

	rdr_log(reader, "Driver Settings: Convention=%s, Protocol=%s, FI=%i, F=%i, N=%i, DI=%i, D=%i, PI1=%i, PI2=%i, II=%i, TXRetries=%i, RXRetries=%i, FilterProtocolBytes=%i", comm.convention ? "Inverse" : "Direct", protocol, comm.FI, F, comm.N, comm.DI, D, comm.PI1, comm.PI2, comm.II, comm.retries.TXRetries, comm.retries.RXRetries, comm.filterprotocolbytes);

	CNXT_SMC_TIMEOUT timeout;
	ret = cnxt_smc_get_config_timeout(specdev()->handle, &timeout);
	coolapi_check_error("cnxt_smc_get_config_timeout", ret);
	rdr_log(reader, "Driver Settings: CardActTime=%i, CardDeactTime=%i, ATRSTime=%i, ATRDTime=%i, BLKTime=%i, CHTime=%i, CHGuardTime=%i, BKGuardTime=%i", timeout.CardActTime, timeout.CardDeactTime, timeout.ATRSTime, timeout.ATRDTime, timeout.BLKTime, timeout.CHTime, timeout.CHGuardTime, timeout.BKGuardTime);

	return OK;
}
Ejemplo n.º 18
0
static int32_t Cool_Transmit (struct s_reader *reader, unsigned char * sent, uint32_t size, uint32_t UNUSED(delay), uint32_t timeout)
{
	int32_t ret;
	specdev()->cardbuflen = 512;//it needs to know max buffer size to respond?

	if (specdev()->read_write_transmit_timeout == -1)
		ret = cnxt_smc_read_write(specdev()->handle, 0, sent, size, specdev()->cardbuffer, &specdev()->cardbuflen, timeout, NULL);
	else
		ret = cnxt_smc_read_write(specdev()->handle, 0, sent, size, specdev()->cardbuffer, &specdev()->cardbuflen, specdev()->read_write_transmit_timeout, NULL);
	coolapi_check_error("cnxt_smc_read_write", ret);

	rdr_ddump_mask(reader, D_DEVICE, sent, size, "COOL Transmit:");
	return OK;
}
Ejemplo n.º 19
0
static int32_t Cool_Reset (struct s_reader *reader, ATR * atr)
{
	int32_t ret;

	if (!reader->ins7e11_fast_reset) {
		//set freq to reader->cardmhz if necessary
		uint32_t clk;

		ret = cnxt_smc_get_clock_freq (specdev()->handle, &clk);
		coolapi_check_error("cnxt_smc_get_clock_freq", ret);
		if (clk/10000 != (uint32_t)reader->cardmhz) {
			rdr_debug_mask(reader, D_DEVICE, "COOL: clock freq: %i, scheduling change to %i for card reset",
					clk, reader->cardmhz*10000);
			call (Cool_SetClockrate(reader, reader->cardmhz));
		}
	}
	else {
		rdr_debug_mask(reader, D_DEVICE, "fast reset needed, restoring transmit parameter for coolstream device %s", reader->device);
		call(Cool_Set_Transmit_Timeout(reader, 0));
		rdr_log(reader, "Doing fast reset");
	}

	//reset card
	ret = cnxt_smc_reset_card (specdev()->handle, ATR_TIMEOUT, NULL, NULL);
	coolapi_check_error("cnxt_smc_reset_card", ret);
	cs_sleepms(50);
	int32_t n = ATR_MAX_SIZE;
	unsigned char buf[ATR_MAX_SIZE];
	ret = cnxt_smc_get_atr (specdev()->handle, buf, &n);
	coolapi_check_error("cnxt_smc_get_atr", ret);

	call (!ATR_InitFromArray (atr, buf, n) != ERROR);
	{
		cs_sleepms(50);
		return OK;
	}
}
Ejemplo n.º 20
0
static void coolapi_dmx_close(void)
{
	if(dmx_opened)
	{
		int32_t result;
		int32_t i;

		for(i = 0; i < MAX_COOL_DMX; i++)
		{
			result = cnxt_dmx_close(dmx_handles[i].handle);
			coolapi_check_error("cnxt_dmx_close", result);
			dmx_handles[i].handle = NULL;
		}
		dmx_opened = 0;
	}
}
Ejemplo n.º 21
0
static int32_t Cool_SetProtocol(struct s_reader *reader, unsigned char *params, uint32_t *UNUSED(length), uint32_t UNUSED(len_request))
{
	struct cool_data *crdr_data = reader->crdr_data;
	unsigned char pps[4], response[6];
	uint8_t len = 0;

	//Driver sets PTSS and PCK on its own
	pps[0] = params[1]; //PPS0
	pps[1] = params[2]; //PPS1

	int32_t ret = cnxt_smc_start_pps(crdr_data->handle, pps, response, &len, 1);
	coolapi_check_error("cnxt_smc_start_pps", ret);
	if(ret)
		{ return ERROR; }
	crdr_data->pps = 1;
	return OK;
}
Ejemplo n.º 22
0
static int32_t Cool_GetStatus (struct s_reader *reader, int32_t * in)
{
	if (cool_kal_opened) {
		int32_t state;
		int32_t ret = cnxt_smc_get_state(specdev()->handle, &state);
		if (ret) {
			coolapi_check_error("cnxt_smc_get_state", ret);
			return ERROR;
		}
		//state = 0 no card, 1 = not ready, 2 = ready
		if (state)
			*in = 1; //CARD, even if not ready report card is in, or it will never get activated
		else
			*in = 0; //NOCARD
	} else {
		*in = 0;
	}
	return OK;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
0
static int32_t Cool_WriteSettings(struct s_reader *reader, struct s_cardreader_settings *s)
{
	struct cool_data *crdr_data = reader->crdr_data;
	//first set freq back to reader->mhz if necessary
	uint32_t clk;
	int32_t ret = cnxt_smc_get_clock_freq(crdr_data->handle, &clk);
	coolapi_check_error("cnxt_smc_get_clock_freq", ret);
	if(clk / 10000 != (uint32_t)reader->mhz)
	{
		rdr_log_dbg(reader, D_DEVICE, "COOL: clock freq: %i, scheduling change to %i", clk, reader->mhz * 10000);
		call(Cool_SetClockrate(reader, reader->mhz));
	}

	uint32_t BLKTime = 0, CHTime = 0;
	uint8_t BKGuardTime = 0;
	switch(reader->protocol_type)
	{
	case ATR_PROTOCOL_TYPE_T1:
		if(reader->BWT > 11)
			{ BLKTime = (reader->BWT - 11); }
		if(reader->CWT > 11)
			{ CHTime = (reader->CWT - 11); }
		if(s->BGT > 11)
			{ BKGuardTime = (s->BGT - 11); }
		else
			{ BKGuardTime = 11; } //For T1, the BGT minimum time shall be 22 work etus. BGT is effectively offset by 11 etus internally.
		if(!crdr_data->pps)
		{
			ret = cnxt_smc_set_F_D_factors(crdr_data->handle, s->F, s->D);
			coolapi_check_error("cnxt_smc_set_F_D_factors", ret);
		}
		break;
	case ATR_PROTOCOL_TYPE_T0:
	case ATR_PROTOCOL_TYPE_T14:
	default:
		BLKTime = 0;
		if(s->WWT > 12)
			{ CHTime = (s->WWT - 12); }
		if(s->BGT > 12)
			{ BKGuardTime = (s->BGT - 12); }
		if(BKGuardTime < 4)
			{ BKGuardTime = 4; } //For T0, the BGT minimum time shall be 16 work etus. BGT is effectively offset by 12 etus internally.
		if(!crdr_data->pps)
		{
			if(reader->protocol_type == ATR_PROTOCOL_TYPE_T14)
			{
				ret = cnxt_smc_set_F_D_factors(crdr_data->handle, 620, 1);
			}
			else
			{
				ret = cnxt_smc_set_F_D_factors(crdr_data->handle, s->F, s->D);
			}
			coolapi_check_error("cnxt_smc_set_F_D_factors", ret);
		}
		break;
	}
	ret = cnxt_smc_set_convention(crdr_data->handle, reader->convention);
	coolapi_check_error("cnxt_smc_set_convention", ret);

	CNXT_SMC_TIMEOUT timeout;
	ret = cnxt_smc_get_config_timeout(crdr_data->handle, &timeout);
	coolapi_check_error("cnxt_smc_get_config_timeout", ret);
	timeout.BLKTime = BLKTime;
	timeout.CHTime = CHTime;
	timeout.CHGuardTime = s->EGT;
	timeout.BKGuardTime = BKGuardTime;
	ret = cnxt_smc_set_config_timeout(crdr_data->handle, timeout);
	coolapi_check_error("cnxt_smc_set_config_timeout", ret);

	Cool_Print_Comm_Parameters(reader);

	return OK;
}