Exemple #1
0
int32_t cardreader_do_ecm(struct s_reader *reader, ECM_REQUEST *er, struct s_ecm_answer *ea)
{
	int32_t rc = -1;
	if((rc = cardreader_do_checkhealth(reader)))
	{
		rdr_log_dbg(reader, D_READER, "%s: cardreader_do_checkhealth returned rc=%d", __func__, rc);
		struct s_client *cl = reader->client;
		if(cl)
		{
			cl->last_srvid = er->srvid;
			cl->last_caid = er->caid;
			cl->last_provid = er->prid;
			cl->last = time((time_t *)0);
		}

		if(reader->csystem_active && reader->csystem && reader->csystem->do_ecm)
		{
			rc = reader->csystem->do_ecm(reader, er, ea);
			rdr_log_dbg(reader, D_READER, "%s: after csystem->do_ecm rc=%d", __func__, rc);
		}
		else
			{ rc = 0; }
	}
	rdr_log_dbg(reader, D_READER, "%s: ret rc=%d", __func__, rc);
	return (rc);
}
Exemple #2
0
static int32_t pcsc_do_api(struct s_reader *pcsc_reader, const uchar *buf, uchar *cta_res, uint16_t *cta_lr, int32_t l)
{
	LONG rv;
	DWORD dwSendLength, dwRecvLength;

	*cta_lr = 0;
	if(!l)
	{
		rdr_log(pcsc_reader, "ERROR: Data length to be send to the pcsc_reader is %d", l);
		return ERROR;
	}

	char tmp[l * 3];
	dwRecvLength = CTA_RES_LEN;

	struct pcsc_data *crdr_data = pcsc_reader->crdr_data;
	if(crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T0)
	{
		//  explanantion as to why we do the test on buf[4] :
		// Issuing a command without exchanging data :
		//To issue a command to the card that does not involve the exchange of data (either sent or received), the send and receive buffers must be formatted as follows.
		//The pbSendBuffer buffer must contain the CLA, INS, P1, and P2 values for the T=0 operation. The P3 value is not sent. (This is to differentiate the header from the case where 256 bytes are expected to be returned.)
		//The cbSendLength parameter must be set to four, the size of the T=0 header information (CLA, INS, P1, and P2).
		//The pbRecvBuffer will receive the SW1 and SW2 status codes from the operation.
		//The pcbRecvLength should be at least two and will be set to two upon return.
		if(buf[4])
			{ dwSendLength = l; }
		else
			{ dwSendLength = l - 1; }
		rdr_log_dbg(pcsc_reader, D_DEVICE, "sending %lu bytes to PCSC : %s", (unsigned long)dwSendLength, cs_hexdump(1, buf, l, tmp, sizeof(tmp)));
		rv = SCardTransmit(crdr_data->hCard, SCARD_PCI_T0, (LPCBYTE) buf, dwSendLength, NULL, (LPBYTE) cta_res, (LPDWORD) &dwRecvLength);
		*cta_lr = dwRecvLength;
	}
	else  if(crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T1)
	{
		dwSendLength = l;
		rdr_log_dbg(pcsc_reader, D_DEVICE, "sending %lu bytes to PCSC : %s", (unsigned long)dwSendLength, cs_hexdump(1, buf, l, tmp, sizeof(tmp)));
		rv = SCardTransmit(crdr_data->hCard, SCARD_PCI_T1, (LPCBYTE) buf, dwSendLength, NULL, (LPBYTE) cta_res, (LPDWORD) &dwRecvLength);
		*cta_lr = dwRecvLength;
	}
	else
	{
		rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC invalid protocol (T=%lu)", (unsigned long)crdr_data->dwActiveProtocol);
		return ERROR;
	}

	rdr_log_dbg(pcsc_reader, D_DEVICE, "received %d bytes from PCSC with rv=%lx : %s", *cta_lr, (unsigned long)rv, cs_hexdump(1, cta_res, *cta_lr, tmp, sizeof(tmp)));

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC doapi (%lx ) (T=%d), %d", (unsigned long)rv, (crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T0 ? 0 :  1), *cta_lr);

	if(rv  == SCARD_S_SUCCESS)
	{
		return OK;
	}
	else
	{
		return ERROR;
	}

}
Exemple #3
0
static int32_t dre_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
{
	def_resp;
	char tmp_dbg[256];
	struct dre_data *csystem_data = reader->csystem_data;
	if(reader->caid == 0x4ae0)
	{
		uchar ecmcmd41[] = { 0x41,
							 0x58, 0x1f, 0x00,     //fixed part, dont change
							 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,   //0x01 - 0x08: next key
							 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,   //0x11 - 0x18: current key
							 0x3b, 0x59, 0x11      //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
						   };
		ecmcmd41[22] = csystem_data->provider;
		memcpy(ecmcmd41 + 4, er->ecm + 8, 16);
		ecmcmd41[20] = er->ecm[6];  //keynumber
		ecmcmd41[21] = 0x58 + er->ecm[25];  //package number
		rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg)));
		rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 24, er->ecm[2] + 2 - 24, tmp_dbg, sizeof(tmp_dbg)));
		if((dre_cmd(ecmcmd41)))     //ecm request
		{
			if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
				{ return ERROR; }       //exit if response is not 90 00
			memcpy(ea->cw, cta_res + 11, 8);
			memcpy(ea->cw + 8, cta_res + 3, 8);

			return OK;
		}
	}
	else
	{

		uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3,  //fixed header?
							 0x9C, 0xDA,       //first three nibbles count up, fourth nibble counts down; all ECMs sent twice
							 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E,   //next key?
							 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD,   //current key?
							 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11,   //key or signature?
							 0x14          //provider
						   };
		memcpy(ecmcmd51 + 1, er->ecm + 5, 0x21);
		rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg)));
		rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg)));
		ecmcmd51[33] = csystem_data->provider;  //no part of sig
		if((dre_cmd(ecmcmd51)))     //ecm request
		{
			if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
				{ return ERROR; }       //exit if response is not 90 00
			DREover(er->ecm, cta_res + 3);
			memcpy(ea->cw, cta_res + 11, 8);
			memcpy(ea->cw + 8, cta_res + 3, 8);
			return OK;
		}
	}
	return ERROR;
}
Exemple #4
0
void cardreader_process_ecm(struct s_reader *reader, struct s_client *cl, ECM_REQUEST *er)
{

	cs_log_dump_dbg(D_ATR, er->ecm, er->ecmlen, "ecm:");

	struct timeb tps, tpe;
	struct s_ecm_answer ea;
	memset(&ea, 0, sizeof(struct s_ecm_answer));
	
	cs_ftime(&tps);
	int32_t rc = cardreader_do_ecm(reader, er, &ea);
	cs_ftime(&tpe);
	
	rdr_log_dbg(reader, D_READER, "%s: cardreader_do_ecm returned rc=%d (ERROR=%d)", __func__, rc, ERROR);

	ea.rc = E_FOUND; //default assume found
	ea.rcEx = 0; //no special flag

	if(rc == ERROR)
	{
		char buf[CS_SERVICENAME_SIZE];
		rdr_log_dbg(reader, D_READER, "Error processing ecm for caid %04X, provid %06X, srvid %04X, servicename: %s",
					   er->caid, er->prid, er->srvid, get_servicename(cl, er->srvid, er->prid, er->caid, buf, sizeof(buf)));
		ea.rc = E_NOTFOUND;
		ea.rcEx = 0;
		ICC_Async_DisplayMsg(reader, "Eer");
	}

	if(rc == E_CORRUPT)
	{
		char buf[CS_SERVICENAME_SIZE];
		rdr_log_dbg(reader, D_READER, "Error processing ecm for caid %04X, provid %06X, srvid %04X, servicename: %s",
					   er->caid, er->prid, er->srvid, get_servicename(cl, er->srvid, er->prid, er->caid, buf, sizeof(buf)));
		ea.rc = E_NOTFOUND;
		ea.rcEx = E2_WRONG_CHKSUM; //flag it as wrong checksum
		memcpy(ea.msglog, "Invalid ecm type for card", 25);
	}

	write_ecm_answer(reader, er, ea.rc, ea.rcEx, ea.cw, ea.msglog, ea.tier, &ea.cw_ex);
	
	cl->lastecm = time((time_t *)0);
	char ecmd5[17 * 3];
	cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));

	rdr_log_dbg(reader, D_READER, "ecm hash: %s real time: %"PRId64" ms", ecmd5, comp_timeb(&tpe, &tps));
	
	reader_post_process(reader);
}
Exemple #5
0
bool detect_db2com_reader(struct s_reader *reader)
{
	struct stat sb;
	if(stat(DEV_MULTICAM, &sb) == -1)
		{ return false; }
	if(stat(reader->device, &sb) == 0)
	{
		if(S_ISCHR(sb.st_mode))
		{
			int32_t dev_major = major(sb.st_rdev);
			int32_t dev_minor = minor(sb.st_rdev);
			if(dev_major == 4 || dev_major == 5)
			{
				int32_t rc;
				switch(dev_minor & 0x3F)
				{
				case 0:
					rc = R_DB2COM1;
					break;
				case 1:
					rc = R_DB2COM2;
					break;
				default:
					return false;
				}
				reader->typ = rc;
			}
			rdr_log_dbg(reader, D_READER, "device is major: %d, minor: %d, typ=%d", dev_major, dev_minor, reader->typ);
		}
	}
	return true;
}
Exemple #6
0
static int32_t griffin_get_emm_type(EMM_PACKET *ep, struct s_reader *rdr)
{
	memcpy(ep->hexserial, ep->emm + 3, 4);
	switch(ep->emm[0])
	{
		case 0x82:
		case 0x83:
			if(memcmp(ep->hexserial, rdr->sa[0], 4) == 0)
			{
				if(DEBUG)
				{
					rdr_log_sensitive(rdr, "SHARED EMM TYPE:%02X SA:{%02X %02X %02X %02X}",
									ep->emm[0], ep->emm[3], ep->emm[4], ep->emm[5], ep->emm[6]);
				}
				ep->type = SHARED;
			}
			if(memcmp(ep->hexserial, rdr->sa[1], 4) == 0)
			{
				if(DEBUG)
				{
					rdr_log_sensitive(rdr, "UNIQUE EMM TYPE:%02X SA:{%02X %02X %02X %02X}",
									ep->emm[0], ep->emm[3], ep->emm[4], ep->emm[5], ep->emm[6]);
				}
				ep->type = UNIQUE;
			}
			break;

		default:
			ep->type = UNKNOWN;
			rdr_log_dbg(rdr, D_EMM, "UNKNOWN EMM TYPE:%02X SA:%02X %02X %02X %02X",
						ep->emm[0], ep->emm[3], ep->emm[4], ep->emm[5], ep->emm[6]);
	}
	return OK;
}
Exemple #7
0
static int32_t pcsc_close(struct s_reader *pcsc_reader)
{
	struct pcsc_data *crdr_data = pcsc_reader->crdr_data;
	rdr_log_dbg(pcsc_reader, D_IFD, "PCSC : Closing device %s", pcsc_reader->device);
	SCardDisconnect(crdr_data->hCard, SCARD_LEAVE_CARD);
	SCardReleaseContext(crdr_data->hContext);
	return OK;
}
Exemple #8
0
static int32_t Sc8in1_DebugSignals(struct s_reader *reader, uint16_t slot, const char *extra)
{
	uint32_t msr;
	if(ioctl(reader->handle, TIOCMGET, &msr) < 0)
		{ return ERROR; }
	rdr_log_dbg(reader, D_DEVICE, "SC8in1: Signals(%s): Slot: %i, DTR: %u, RTS: %u",
				   extra, slot, msr & TIOCM_DTR ? 1 : 0, msr & TIOCM_RTS ? 1 : 0);
	return OK;
}
Exemple #9
0
static bool db2com_DTR_RTS(struct s_reader *reader, int32_t *dtr, int32_t *rts)
{
	int32_t rc;
	uint16_t msr;
	uint16_t rts_bits[2] = { 0x10, 0x800 };
	uint16_t dtr_bits[2] = {0x100,     0 };
	int32_t mcport = reader->typ == R_DB2COM2;

	rc = ioctl(reader->fdmc, MULTICAM_GET_PCDAT, &msr);
	if(rc < 0)
		{ return ERROR; }

	if(dtr)
	{
		rdr_log_dbg(reader, D_DEVICE, "%s DTR:%s", __func__, *dtr ? "set" : "clear");
		if(dtr_bits[mcport])
		{
			if(*dtr)
				{ msr &= (uint16_t)(~dtr_bits[mcport]); }
			else
				{ msr |= dtr_bits[mcport]; }
			rc = ioctl(reader->fdmc, MULTICAM_SET_PCDAT, &msr);
		}
		else
		{
			rc = 0; // Dummy, can't handle using multicam.o
		}
	}

	if(rts)
	{
		rdr_log_dbg(reader, D_DEVICE, "%s RTS:%s", __func__, *rts ? "set" : "clear");
		if(*rts)
			{ msr &= (uint16_t)(~rts_bits[mcport]); }
		else
			{ msr |= rts_bits[mcport]; }
		rc = ioctl(reader->fdmc, MULTICAM_SET_PCDAT, &msr);
	}

	if(rc < 0)
		{ return ERROR; }
	return OK;
}
Exemple #10
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;
}
Exemple #11
0
static int32_t dre_set_provider_info(struct s_reader *reader)
{
	def_resp;
	int32_t i;
	uchar cmd59[] = { 0x59, 0x14 };   // subscriptions
	uchar cmd5b[] = { 0x5b, 0x00, 0x14 }; //validity dates
	struct dre_data *csystem_data = reader->csystem_data;

	cs_clear_entitlement(reader);

	cmd59[1] = csystem_data->provider;
	if((dre_cmd(cmd59)))      //ask subscription packages, returns error on 0x11 card
	{
		uchar pbm[32];
		char tmp_dbg[65];
		memcpy(pbm, cta_res + 3, cta_lr - 6);
		rdr_log_dbg(reader, D_READER, "pbm: %s", cs_hexdump(0, pbm, 32, tmp_dbg, sizeof(tmp_dbg)));

		if(pbm[0] == 0xff)
			{ rdr_log(reader, "no active packages"); }
		else
			for(i = 0; i < 32; i++)
				if(pbm[i] != 0xff)
				{
					cmd5b[1] = i;
					cmd5b[2] = csystem_data->provider;
					dre_cmd(cmd5b);   //ask for validity dates

					time_t start;
					time_t end;
					start = (cta_res[3] << 24) | (cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6];
					end = (cta_res[7] << 24) | (cta_res[8] << 16) | (cta_res[9] << 8) | cta_res[10];

					struct tm temp;

					localtime_r(&start, &temp);
					int32_t startyear = temp.tm_year + 1900;
					int32_t startmonth = temp.tm_mon + 1;
					int32_t startday = temp.tm_mday;
					localtime_r(&end, &temp);
					int32_t endyear = temp.tm_year + 1900;
					int32_t endmonth = temp.tm_mon + 1;
					int32_t endday = temp.tm_mday;
					rdr_log(reader, "active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i", i, startyear, startmonth, startday,
							endyear, endmonth, endday);
					cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), 0, 0, start, end, 1, 1);
				}
	}
	return OK;
}
Exemple #12
0
int32_t cardreader_do_checkhealth(struct s_reader *reader)
{
	struct s_client *cl = reader->client;
	if(reader_card_inserted(reader))
	{
		if(reader->card_status == NO_CARD || reader->card_status == UNKNOWN)
		{
			rdr_log(reader, "card detected");
			led_status_card_detected();
			reader->card_status = CARD_NEED_INIT;
			add_job(cl, ACTION_READER_RESET, NULL, 0);
		}
	}
	else
	{
		rdr_log_dbg(reader, D_READER, "%s: !reader_card_inserted", __func__);
		if(reader->card_status == CARD_INSERTED || reader->card_status == CARD_NEED_INIT)
		{
			rdr_log(reader, "card ejected");
			reader_nullcard(reader);
			if(reader->csystem && reader->csystem->card_done)
				reader->csystem->card_done(reader);
			NULLFREE(reader->csystem_data);
			if(cl)
			{
				cl->lastemm = 0;
				cl->lastecm = 0;
			}
			led_status_card_ejected();
		}
		reader->card_status = NO_CARD;
	}
	rdr_log_dbg(reader, D_READER, "%s: reader->card_status = %d, ret = %d", __func__,
				   reader->card_status, reader->card_status == CARD_INSERTED);
	return reader->card_status == CARD_INSERTED;
}
Exemple #13
0
static int32_t pcsc_activate_card(struct s_reader *pcsc_reader, uchar *atr, uint16_t *atr_size)
{
	struct pcsc_data *crdr_data = pcsc_reader->crdr_data;
	LONG rv;
	DWORD dwState, dwAtrLen, dwReaderLen;
	unsigned char pbAtr[ATR_MAX_SIZE];
	char tmp[sizeof(pbAtr) * 3 + 1];

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC initializing card in (%s)", crdr_data->pcsc_name);
	dwAtrLen = sizeof(pbAtr);
	dwReaderLen = 0;

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC resetting card in (%s) with handle %ld", crdr_data->pcsc_name, (long)(crdr_data->hCard));
	rv = SCardReconnect(crdr_data->hCard, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,  SCARD_RESET_CARD, &crdr_data->dwActiveProtocol);

	if(rv != SCARD_S_SUCCESS)
	{
		rdr_log_dbg(pcsc_reader, D_DEVICE, "ERROR: PCSC failed to reset card (%lx)", (unsigned long)rv);
		return ERROR;
	}

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC resetting done on card in (%s)", crdr_data->pcsc_name);
	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC Protocol (T=%d)", (crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T0 ? 0 :  1));

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC getting ATR for card in (%s)", crdr_data->pcsc_name);
	rv = SCardStatus(crdr_data->hCard, NULL, &dwReaderLen, &dwState, &crdr_data->dwActiveProtocol, pbAtr, &dwAtrLen);
	if(rv == SCARD_S_SUCCESS)
	{
		rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC Protocol (T=%d)", (crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T0 ? 0 :  1));
		memcpy(atr, pbAtr, dwAtrLen);
		*atr_size = dwAtrLen;

		rdr_log(pcsc_reader, "ATR: %s", cs_hexdump(1, (uchar *)pbAtr, dwAtrLen, tmp, sizeof(tmp)));
		memcpy(pcsc_reader->card_atr, pbAtr, dwAtrLen);
		pcsc_reader->card_atr_length = dwAtrLen;
		return OK;
	}
	else
	{
		rdr_log_dbg(pcsc_reader, D_DEVICE, "ERROR: PCSC failed to get ATR for card (%lx)", (unsigned long)rv);
	}

	return ERROR;
}
Exemple #14
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;
	}
}
Exemple #15
0
static int32_t dre_set_provider_info(struct s_reader *reader)
{
	def_resp;
	int32_t i;
    int subscr_cmd_len = 4;
    uchar subscr[4];// = { 0x59, 0x14 };   // subscriptions
    uchar dates[] = { 0x5b, 0x00, 0x14 }; //validity dates
    uchar subscr_len = 0, n = 0;
	struct dre_data *csystem_data = reader->csystem_data;

	cs_clear_entitlement(reader);

    switch(csystem_data->provider)
    {
        case 0x02:
        case 0x03:
            subscr[0] = 0x84;
            subscr[1] = 0;
            subscr[2] = 0x5F;
            subscr[3] = csystem_data->provider;
            dates[0] = 0x85;
            subscr_len = 0x5F;
            break;
        case 0x18:
        case 0x19:
        case 0x1A:
            subscr[0] = 0x94;
            subscr[1] = 0;
            subscr[2] = 0x5F;
            subscr[3] = csystem_data->provider;
            dates[0] = 0x95;
            subscr_len = 0x5F;
            break;
        default:
            subscr[0] = 0x59;
            subscr[1] = csystem_data->provider;
            subscr_len = 0x20;
            subscr_cmd_len = 2;
    }

chk_subscr:
    
    if((dre_script(subscr, subscr_cmd_len, 0, 0, 0)))      //ask subscription packages, returns error on 0x11 card
    {
        uchar pbm[subscr_len];
        char tmp_dbg[subscr_len*2+1];
		memcpy(pbm, cta_res + 3, cta_lr - 6);
        rdr_log_dbg(reader, D_READER, "pbm: %s", cs_hexdump(0, pbm, subscr_len, tmp_dbg, sizeof(tmp_dbg)));

        for(i = 0; i < subscr_len; i++)
            if(pbm[i] != 0xff)
            {
                dates[1] = i;
                dates[2] = csystem_data->provider;
                dre_cmd(dates);   //ask for validity dates

                time_t start;
                time_t end;
                start = (cta_res[3] << 24) | (cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6];
                end = (cta_res[7] << 24) | (cta_res[8] << 16) | (cta_res[9] << 8) | cta_res[10];

                struct tm temp;

                localtime_r(&start, &temp);
                int32_t startyear = temp.tm_year + 1900;
                int32_t startmonth = temp.tm_mon + 1;
                int32_t startday = temp.tm_mday;
                localtime_r(&end, &temp);
                int32_t endyear = temp.tm_year + 1900;
                int32_t endmonth = temp.tm_mon + 1;
                int32_t endday = temp.tm_mday;
                rdr_log(reader, "active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i", i+n, startyear, startmonth, startday,
                        endyear, endmonth, endday);
                cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), 0, i+n, start, end, 5, 1);
            }
    }
    
    if(subscr_len == 0x5F) // read second part subscription packages, for DRE3 and DRE4
    {
        subscr[1] = 0x5F;
        subscr[2] = 0x21;
        subscr_len = 0x21;
        n = 0x5F;
        goto chk_subscr;
    }

	return OK;
}
Exemple #16
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;
}
Exemple #17
0
bool cardreader_init(struct s_reader *reader)
{
	struct s_client *client = reader->client;
	client->typ = 'r';
	int8_t i = 0;
	set_localhost_ip(&client->ip);
	while((cardreader_device_init(reader) == 2) && i < 10)
	{
		cs_sleepms(2000);
		if(!ll_contains(configured_readers, reader) || !is_valid_client(client) || reader->enable != 1)
			{ return false; }
		i++;
	}
	if (i >= 10)
	{
		reader->card_status = READER_DEVICE_ERROR;
		cardreader_close(reader);
		reader->enable = 0;
		return false;
	}
	else 
	{
		if(reader->typ == R_INTERNAL)
		{
			if(boxtype_is("dm8000") || boxtype_is("dm800") || boxtype_is("dm800se"))
				{reader->cardmhz = 2700;}
			if(boxtype_is("dm500") || boxtype_is("dm600pvr"))
				{reader->cardmhz = 3150;}
			if(boxtype_is("dm7025"))
				{reader->cardmhz = 8300;}
			if((!strncmp(boxtype_get(), "vu", 2 ))||(boxtype_is("ini-8000am")))
				{reader->cardmhz = 2700; reader->mhz = 450;} // only one speed for vu+ and Atemio Nemesis due to usage of TDA8024
		}
		if((reader->cardmhz > 2000) && (reader->typ != R_SMART))
		{
			rdr_log(reader, "Reader initialized (device=%s, detect=%s%s, pll max=%.2f MHz, wanted mhz=%.2f MHz)",
					reader->device,
					reader->detect & 0x80 ? "!" : "",
					RDR_CD_TXT[reader->detect & 0x7f],
					(float)reader->cardmhz / 100,
					(float)reader->mhz / 100);
			rdr_log(reader,"Reader sci internal, detected box type: %s", boxtype_get());
		}
		else
		{
			if (reader->typ == R_SMART || is_smargo_reader(reader))
			{
				rdr_log_dbg(reader, D_IFD, "clocking for smartreader with smartreader or smargo protocol");
				if (reader->cardmhz >= 2000) reader->cardmhz =  369; else
				if (reader->cardmhz >= 1600) reader->cardmhz = 1600; else
				if (reader->cardmhz >= 1200) reader->cardmhz = 1200; else
				if (reader->cardmhz >= 961)  reader->cardmhz =  961; else
				if (reader->cardmhz >= 800)  reader->cardmhz =  800; else
				if (reader->cardmhz >= 686)  reader->cardmhz =  686; else
				if (reader->cardmhz >= 600)  reader->cardmhz =  600; else
				if (reader->cardmhz >= 534)  reader->cardmhz =  534; else
				if (reader->cardmhz >= 480)  reader->cardmhz =  480; else
				if (reader->cardmhz >= 436)  reader->cardmhz =  436; else
				if (reader->cardmhz >= 400)  reader->cardmhz =  400; else
				if (reader->cardmhz >= 369)  reader->cardmhz =  369; else
				if (reader->cardmhz == 357)  reader->cardmhz =  369; else // 357 not a default smartreader setting
				if (reader->cardmhz >= 343)  reader->cardmhz =  343; else 
				reader->cardmhz =  320;
				if (reader->mhz >= 1600) reader->mhz = 1600; else
				if (reader->mhz >= 1200) reader->mhz = 1200; else
				if (reader->mhz >= 961)  reader->mhz =  961; else
				if (reader->mhz >= 900)  reader->mhz =  900; else
				if (reader->mhz >= 800)  reader->mhz =  800; else
				if (reader->mhz >= 686)  reader->mhz =  686; else
				if (reader->mhz >= 600)  reader->mhz =  600; else
				if (reader->mhz >= 534)  reader->mhz =  534; else
				if (reader->mhz >= 480)  reader->mhz =  480; else
				if (reader->mhz >= 436)  reader->mhz =  436; else
				if (reader->mhz >= 400)  reader->mhz =  369; else
				if (reader->mhz >= 369)  reader->mhz =  369; else
				if (reader->mhz == 357)  reader->mhz =  369; else // 357 not a default smartreader setting
				if (reader->mhz >= 343)  reader->mhz =  343; else 
				reader->mhz =  320;
	    	}
			if ((reader->typ == R_SMART || is_smargo_reader(reader)) && reader->autospeed == 1)
			{
				rdr_log(reader, "Reader initialized (device=%s, detect=%s%s, mhz= AUTO, cardmhz=%d)",
						reader->device,
						reader->detect & 0x80 ? "!" : "",
						RDR_CD_TXT[reader->detect & 0x7f],
						reader->cardmhz);
			} else {
				rdr_log(reader, "Reader initialized (device=%s, detect=%s%s, mhz=%d, cardmhz=%d)",
						reader->device,
						reader->detect & 0x80 ? "!" : "",
						RDR_CD_TXT[reader->detect & 0x7f],
						reader->mhz,
						reader->cardmhz);
				if (reader->typ == R_INTERNAL && !(reader->cardmhz > 2000))
					rdr_log(reader,"Reader sci internal, detected box type: %s", boxtype_get());
			}
		}
		return true;
	}
}
Exemple #18
0
static void process_clients(void)
{
	int32_t i, k, j, rc, pfdcount = 0;
	struct s_client *cl;
	struct s_reader *rdr;
	struct pollfd *pfd;
	struct s_client **cl_list;
	struct timeb start, end;  // start time poll, end time poll
	uint32_t cl_size = 0;

	uchar buf[10];

	if(pipe(thread_pipe) == -1)
	{
		printf("cannot create pipe, errno=%d\n", errno);
		exit(1);
	}

	cl_size = chk_resize_cllist(&pfd, &cl_list, 0, 100);

	pfd[pfdcount].fd = thread_pipe[0];
	pfd[pfdcount].events = POLLIN | POLLPRI;
	cl_list[pfdcount] = NULL;

	while(!exit_oscam)
	{
		pfdcount = 1;

		//connected tcp clients
		for(cl = first_client->next; cl; cl = cl->next)
		{
			if(cl->init_done && !cl->kill && cl->pfd && cl->typ == 'c' && !cl->is_udp)
			{
				if(cl->pfd && !cl->thread_active)
				{
					cl_size = chk_resize_cllist(&pfd, &cl_list, cl_size, pfdcount);
					cl_list[pfdcount] = cl;
					pfd[pfdcount].fd = cl->pfd;
					pfd[pfdcount++].events = POLLIN | POLLPRI;
				}
			}
			//reader:
			//TCP:
			//  - TCP socket must be connected
			//  - no active init thread
			//UDP:
			//  - connection status ignored
			//  - no active init thread
			rdr = cl->reader;
			if(rdr && cl->typ == 'p' && cl->init_done)
			{
				if(cl->pfd && !cl->thread_active && ((rdr->tcp_connected && rdr->ph.type == MOD_CONN_TCP) || (rdr->ph.type == MOD_CONN_UDP)))
				{
					cl_size = chk_resize_cllist(&pfd, &cl_list, cl_size, pfdcount);
					cl_list[pfdcount] = cl;
					pfd[pfdcount].fd = cl->pfd;
					pfd[pfdcount++].events = (POLLIN | POLLPRI);
				}
			}
		}

		//server (new tcp connections or udp messages)
		for(k = 0; k < CS_MAX_MOD; k++)
		{
			struct s_module *module = &modules[k];
			if((module->type & MOD_CONN_NET))
			{
				for(j = 0; j < module->ptab.nports; j++)
				{
					if(module->ptab.ports[j].fd)
					{
						cl_size = chk_resize_cllist(&pfd, &cl_list, cl_size, pfdcount);
						cl_list[pfdcount] = NULL;
						pfd[pfdcount].fd = module->ptab.ports[j].fd;
						pfd[pfdcount++].events = (POLLIN | POLLPRI);
					}
				}
			}
		}

		if(pfdcount >= 1024)
			{ cs_log("WARNING: too many users!"); }
		cs_ftime(&start); // register start time
		rc = poll(pfd, pfdcount, 5000);
		if(rc < 1) { continue; }
		cs_ftime(&end); // register end time

		for(i = 0; i < pfdcount && rc > 0; i++)
		{
			if(pfd[i].revents == 0) { continue; }  // skip sockets with no changes
			rc--; //event handled!
			cs_log_dbg(D_TRACE, "[OSCAM] new event %d occurred on fd %d after %"PRId64" ms inactivity", pfd[i].revents,
						  pfd[i].fd, comp_timeb(&end, &start));
			//clients
			cl = cl_list[i];
			if(cl && !is_valid_client(cl))
				{ continue; }

			if(pfd[i].fd == thread_pipe[0] && (pfd[i].revents & (POLLIN | POLLPRI)))
			{
				// a thread ended and cl->pfd should be added to pollfd list again (thread_active==0)
				int32_t len = read(thread_pipe[0], buf, sizeof(buf));
				if(len == -1)
				{
					cs_log_dbg(D_TRACE, "[OSCAM] Reading from pipe failed (errno=%d %s)", errno, strerror(errno));
				}
				cs_log_dump_dbg(D_TRACE, buf, len, "[OSCAM] Readed:");
				continue;
			}

			//clients
			// message on an open tcp connection
			if(cl && cl->init_done && cl->pfd && (cl->typ == 'c' || cl->typ == 'm'))
			{
				if(pfd[i].fd == cl->pfd && (pfd[i].revents & (POLLHUP | POLLNVAL | POLLERR)))
				{
					//client disconnects
					kill_thread(cl);
					continue;
				}
				if(pfd[i].fd == cl->pfd && (pfd[i].revents & (POLLIN | POLLPRI)))
				{
					add_job(cl, ACTION_CLIENT_TCP, NULL, 0);
				}
			}


			//reader
			// either an ecm answer, a keepalive or connection closed from a proxy
			// physical reader ('r') should never send data without request
			rdr = NULL;
			struct s_client *cl2 = NULL;
			if(cl && cl->typ == 'p')
			{
				rdr = cl->reader;
				if(rdr)
					{ cl2 = rdr->client; }
			}

			if(rdr && cl2 && cl2->init_done)
			{
				if(cl2->pfd && pfd[i].fd == cl2->pfd && (pfd[i].revents & (POLLHUP | POLLNVAL | POLLERR)))
				{
					//connection to remote proxy was closed
					//oscam should check for rdr->tcp_connected and reconnect on next ecm request sent to the proxy
					network_tcp_connection_close(rdr, "closed");
					rdr_log_dbg(rdr, D_READER, "connection closed");
				}
				if(cl2->pfd && pfd[i].fd == cl2->pfd && (pfd[i].revents & (POLLIN | POLLPRI)))
				{
					add_job(cl2, ACTION_READER_REMOTE, NULL, 0);
				}
			}


			//server sockets
			// new connection on a tcp listen socket or new message on udp listen socket
			if(!cl && (pfd[i].revents & (POLLIN | POLLPRI)))
			{
				for(k = 0; k < CS_MAX_MOD; k++)
				{
					struct s_module *module = &modules[k];
					if((module->type & MOD_CONN_NET))
					{
						for(j = 0; j < module->ptab.nports; j++)
						{
							if(module->ptab.ports[j].fd && module->ptab.ports[j].fd == pfd[i].fd)
							{
								accept_connection(module, k, j);
							}
						}
					}
				}
			}
		}
		cs_ftime(&start); // register start time for new poll next run
		first_client->last = time((time_t *)0);
	}
	NULLFREE(pfd);
	NULLFREE(cl_list);
	return;
}
Exemple #19
0
static int32_t dre_command(struct s_reader *reader, const uchar *cmd, int32_t cmdlen, unsigned char *cta_res, uint16_t *p_cta_lr, 
                                                            uint8_t crypted, uint8_t keynum, uint8_t dre_v, uint8_t cmd_type)
                                                            //attention: inputcommand will be changed!!!! answer will be in cta_res, length cta_lr ; returning 1 = no error, return ERROR = err
{
	uchar startcmd[] = { 0x80, 0xFF, 0x10, 0x01, 0x05 };  //any command starts with this,
	//last byte is nr of bytes of the command that will be sent
	//after the startcmd
	//response on startcmd+cmd:     = { 0x61, 0x05 }  //0x61 = "OK", last byte is nr. of bytes card will send
	uchar reqans[] = { 0x00, 0xC0, 0x00, 0x00, 0x08 };    //after command answer has to be requested,
	//last byte must be nr. of bytes that card has reported to send
	uchar command[256];
	uchar checksum;
	char tmp[256];
	int32_t headerlen = sizeof(startcmd);

    if(dre_v > 0)
    {
        startcmd[1] = 0;
        startcmd[2] = crypted;
        startcmd[3] = keynum;
    }

    startcmd[4] = cmdlen + 3 - cmd_type; //commandlength + type + len + checksum bytes
	memcpy(command, startcmd, headerlen);
    command[headerlen++] = cmd_type ? 0x86 : CMD_BYTE;  //type
    command[headerlen++] = cmdlen + (cmd_type == 1 ? 0 : 1);    //len = command + 1 checksum byte
	memcpy(command + headerlen, cmd, cmdlen);

    if(!cmd_type)
    {
        checksum = ~xor(cmd, cmdlen);
        //rdr_log_dbg(reader, D_READER, "Checksum: %02x", checksum);
        cmdlen += headerlen;
        command[cmdlen++] = checksum;
    }
    else cmdlen += headerlen;

	reader_cmd2icc(reader, command, cmdlen, cta_res, p_cta_lr);

	if((*p_cta_lr != 2) || (cta_res[0] != OK_RESPONSE))
	{
		rdr_log(reader, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
		rdr_log(reader, "unexpected answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
		return ERROR;           //error
	}

    rdr_log_dbg(reader, D_READER, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
    rdr_log_dbg(reader, D_READER, "answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));

	reqans[4] = cta_res[1];   //adapt length byte
	reader_cmd2icc(reader, reqans, 5, cta_res, p_cta_lr);

	if(cta_res[0] != CMD_BYTE)
	{
		rdr_log(reader, "unknown response: cta_res[0] expected to be %02x, is %02x", CMD_BYTE, cta_res[0]);
		return ERROR;
	}

	if((cta_res[1] == 0x03) && (cta_res[2] == 0xe2))
	{
		switch(cta_res[3+dre_v])
		{
		case 0xe1:
			rdr_log(reader, "checksum error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
		case 0xe2:
			rdr_log(reader, "wrong cmd len: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
		case 0xe3:
			rdr_log(reader, "illegal command: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
        case 0xe4:
            rdr_log(reader, "wrong adress type: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe5:
            rdr_log(reader, "wrong CMD param: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe6:
            rdr_log(reader, "wrong UA: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe7:
            rdr_log(reader, "wrong group: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe8:
            rdr_log(reader, "wrong key num: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xeb:
            rdr_log(reader, "No key or subscribe : %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
		case 0xec:
			rdr_log(reader, "wrong signature: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
        case 0xed:
            rdr_log(reader, "wrong provider: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xef:
            rdr_log(reader, "wrong GEO code: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
		default:
			rdr_log_dbg(reader, D_READER, "unknown error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
		}
		return ERROR;           //error
	}

	int32_t length_excl_leader = *p_cta_lr;

	if((cta_res[*p_cta_lr - 2] == 0x90) && (cta_res[*p_cta_lr - 1] == 0x00))
		{ length_excl_leader -= 2; }

	checksum = ~xor(cta_res + 2, length_excl_leader - 3);

	if(cta_res[length_excl_leader - 1] != checksum)
	{
		rdr_log(reader, "checksum does not match, expected %02x received %02x:%s", checksum,
				cta_res[length_excl_leader - 1], cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
		return ERROR;           //error
	}
	return OK;
}
Exemple #20
0
int32_t Protocol_T1_Command(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr)
{
	uint8_t block_data[T1_BLOCK_MAX_SIZE];
	uint8_t rsp_type, bytes, nr, wtx;
	uint16_t counter;
	int32_t ret, timeout;
	bool more;
	uint32_t block_length = 0;
	if(command[1] == T1_BLOCK_S_IFS_REQ)
	{
		uint8_t inf = command[3];

		/* Create an IFS request S-Block */
		timeout = ICC_Async_GetTimings(reader, reader->CWT);  // we are going to send: CWT timeout
		//cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time
		ret = T1_Block_SendSBlock(reader, block_data, T1_BLOCK_S_IFS_REQ, 1, &inf, timeout);
		rdr_log_dbg(reader, D_IFD, "Protocol: Sending block S(IFS request, %d)", inf);

		/* Receive a block */

		timeout = ICC_Async_GetTimings(reader, reader->BWT); // we are going to receive so set Block Waiting Timeout!
		//cs_sleepus(reader->block_delay); // we were sending, now receiving so wait BGT time
		ret = Protocol_T1_ReceiveBlock(reader, block_data, &block_length, &rsp_type, timeout);

		if(ret == OK)
		{
			/* Positive IFS Response S-Block received */
			if(rsp_type == T1_BLOCK_S_IFS_RES)
			{
				rdr_log_dbg(reader, D_IFD, "Protocol: Received block S(IFS response, %d)", block_data[3]);
			}
		}

		return ret;
	}
	else if(command[1] == T1_BLOCK_S_RESYNCH_REQ)
	{
		/* Create an Resynch request S-Block */
		timeout = ICC_Async_GetTimings(reader, reader->CWT);  // we are going to send: CWT timeout
		//cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time
		ret = T1_Block_SendSBlock(reader, block_data, T1_BLOCK_S_RESYNCH_REQ, 0, NULL, timeout);
		rdr_log_dbg(reader, D_IFD, "Protocol: Sending block S(RESYNCH request)");

		/* Receive a block */
		timeout = ICC_Async_GetTimings(reader, reader->BWT); // we are going to receive so set Block Waiting Timeout!
		//cs_sleepus(reader->block_delay); // we were sending, now receiving so wait BGT time
		ret = Protocol_T1_ReceiveBlock(reader, block_data, &block_length, &rsp_type, timeout);

		if(ret == OK)
		{
			/* Positive IFS Response S-Block received */
			if(rsp_type == T1_BLOCK_S_RESYNCH_RES)
			{
				rdr_log_dbg(reader, D_IFD, "Protocol: Received block S(RESYNCH response)");
				reader->ns = 0;
			}
		}
		return ret;
	}

	/* Calculate the number of bytes to send */
	counter = 0;
	bytes = MIN(command_len, reader->ifsc);

	/* See if chaining is needed */
	more = (command_len > reader->ifsc);

	/* Increment ns */
	reader->ns = (reader->ns == 1) ? 0 : 1; //toggle from 0 to 1 and back

	/* Create an I-Block */
	timeout = ICC_Async_GetTimings(reader, reader->CWT);  // we are going to send: CWT timeout
	//cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time
	ret = T1_Block_SendIBlock(reader, block_data, bytes, command, reader->ns, more, timeout);
	rdr_log_dbg(reader, D_IFD, "Sending block I(%d,%d)", reader->ns, more);

	while((ret == OK) && more)
	{
		/* Receive a block */

		timeout = ICC_Async_GetTimings(reader, reader->BWT); // we are going to receive so set Block Waiting Timeout!
		//cs_sleepus(reader->block_delay); // we were sending, now receiving so wait BGT time
		ret = Protocol_T1_ReceiveBlock(reader, block_data, &block_length, &rsp_type, timeout);

		if(ret == OK)
		{
			/* Positive ACK R-Block received */
			if(rsp_type == T1_BLOCK_R_OK)
			{
				rdr_log_dbg(reader, D_IFD, "Protocol: Received block R(%d)", T1_Block_GetNR(block_data));

				/* Increment ns  */
				reader->ns = (reader->ns == 1) ? 0 : 1; //toggle from 0 to 1 and back

				/* Calculate the number of bytes to send */
				counter += bytes;
				bytes = MIN(command_len - counter, reader->ifsc);

				/* See if chaining is needed */
				more = (command_len - counter > reader->ifsc);

				/* Send an I-Block */
				timeout = ICC_Async_GetTimings(reader, reader->CWT);  // we are going to send: CWT timeout
				//cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time
				ret = T1_Block_SendIBlock(reader, block_data, bytes, command + counter, reader->ns, more, timeout);
				rdr_log_dbg(reader, D_IFD, "Protocol: Sending block I(%d,%d)", reader->ns, more);

			}
			else
			{
				rdr_log_dbg(reader, D_TRACE, "ERROR: T1 Command %02X not implemented", rsp_type);
				return ERROR;
			}
		}
		else
		{
			rdr_log_dbg(reader, D_TRACE, "ERROR: T1 Command returned error");
			return ERROR;
		}
	}

	/* Reset counter */
	counter = 0;
	more = 1;
	wtx = 1;

	while((ret == OK) && more)
	{

		/* Receive a block */
		timeout = ICC_Async_GetTimings(reader, wtx * reader->BWT); // we are going to receive so set Block Waiting Timeout!
		//cs_sleepus(reader->block_delay); // we were sending, now receiving so wait BGT time
		ret = Protocol_T1_ReceiveBlock(reader, block_data, &block_length, &rsp_type, timeout);
		wtx = 1; // reset WTX value since its only valid for first received I block

		if(ret == OK)
		{
			if(rsp_type == T1_BLOCK_I)
			{
				rdr_log_dbg(reader, D_IFD, "Protocol: Received block I(%d,%d)", T1_Block_GetNS(block_data), T1_Block_GetMore(block_data));

				bytes = T1_Block_GetLen(block_data);

				/* Calculate nr */
				nr = (T1_Block_GetNS(block_data) + 1) % 2;

				if(counter + bytes > T1_BLOCK_MAX_SIZE)
				{
					return ERROR;
				}

				memcpy(rsp + counter, block_data + 3, bytes);
				counter += bytes;

				/* See if chaining is requested */
				more = T1_Block_GetMore(block_data);

				if(more)
				{
					/* Send R-Block */
					timeout = ICC_Async_GetTimings(reader, reader->CWT);  // we are going to send: CWT timeout
					//cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time
					ret = T1_Block_SendRBlock(reader, block_data, T1_BLOCK_R_OK, nr, timeout);
					rdr_log_dbg(reader, D_IFD, "Protocol: Sending block R(%d)", nr);
				}
			}
			else if(rsp_type == T1_BLOCK_S_WTX_REQ)      /* WTX Request S-Block received */
			{
				/* Get wtx multiplier */
				wtx = block_data[3];
				rdr_log_dbg(reader, D_IFD, "Protocol: Received block S(WTX request, %d)", wtx);

				/* Send an WTX response S-Block */
				timeout = ICC_Async_GetTimings(reader, reader->CWT);  // we are going to send: CWT timeout
				//cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time
				ret = T1_Block_SendSBlock(reader, block_data, T1_BLOCK_S_WTX_RES, 1, &wtx, timeout);
				rdr_log_dbg(reader, D_IFD, "Protocol: Sending block S(WTX response, %d)", wtx);
			}
			else
			{
				rdr_log_dbg(reader, D_TRACE, "ERROR: T1 Command %02X not implemented in Receive Block", rsp_type);
				ret = ERROR; //not implemented
			}
		}
	}

	if(ret == OK)
	{
		*lr = counter;
	}

	return ret;
}
Exemple #21
0
static int32_t dre_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
{
	def_resp;
	uint16_t overcryptId;
	uint8_t tmp[16];
	char tmp_dbg[256];
	struct dre_data *csystem_data = reader->csystem_data;
	if(reader->caid == 0x4ae0)
	{
		uchar ecmcmd41[] = { 0x41,
							 0x58, 0x1f, 0x00,     //fixed part, dont change
							 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,   //0x01 - 0x08: next key
							 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,   //0x11 - 0x18: current key
							 0x3b, 0x59, 0x11      //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
						   };
		ecmcmd41[22] = csystem_data->provider;
		memcpy(ecmcmd41 + 4, er->ecm + 8, 16);
		ecmcmd41[20] = er->ecm[6];  //keynumber
		ecmcmd41[21] = 0x58 + er->ecm[25];  //package number
		rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg)));
		rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 24, er->ecm[2] + 2 - 24, tmp_dbg, sizeof(tmp_dbg)));
		if((dre_cmd(ecmcmd41)))     //ecm request
		{
			if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
				{ return ERROR; }       //exit if response is not 90 00
			memcpy(ea->cw, cta_res + 11, 8);
			memcpy(ea->cw + 8, cta_res + 3, 8);

			return OK;
		}
	}

    else if(reader->caid == 0x4ae1)
    {
        if(csystem_data->provider == 0x11 || csystem_data->provider == 0x14)
        {
            uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3,  //fixed header?
                                 0x9C, 0xDA,       //first three nibbles count up, fourth nibble counts down; all ECMs sent twice
                                 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E,   //next key?
                                 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD,   //current key?
                                 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11,   //key or signature?
                                 0x14          //provider
                               };
            memcpy(ecmcmd51 + 1, er->ecm + 5, 0x21);
            rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg)));
            rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg)));
            ecmcmd51[33] = csystem_data->provider;  //no part of sig

            if((dre_cmd(ecmcmd51)))     //ecm request
            {
                if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
                    { return ERROR; }       //exit if response is not 90 00

                if(er->ecm[2] >= 46 && er->ecm[43] == 1 && csystem_data->provider == 0x11)
                {
                    memcpy(tmp, cta_res + 11, 8);
                    memcpy(tmp + 8, cta_res + 3, 8);
                    overcryptId = b2i(2, &er->ecm[44]);
                    rdr_log_dbg(reader, D_READER, "ICG ID: %04X", overcryptId);
                    Drecrypt2OverCW(overcryptId,tmp);
                    if(isValidDCW(tmp))
                    {
                        memcpy(ea->cw, tmp, 16);
                        return OK;
                    }
                    return ERROR;
                }

                DREover(reader, er->ecm, cta_res + 3);

                if(isValidDCW(cta_res + 3))
                {
                    memcpy(ea->cw, cta_res + 11, 8);
                    memcpy(ea->cw + 8, cta_res + 3, 8);
                    return OK;
                }
            }
        }
        else if((csystem_data->provider == 0x02 || csystem_data->provider == 0x03) && er->ecm[3] == 3)
        {
            // DRE 3

            if (er->ecm[4] == 2)
            {
                memcpy( ea->cw   , &er->ecm[42], 8);
                memcpy(&ea->cw[8], &er->ecm[34], 8);
                return OK;
            }

            uchar cmdlen;
            uchar crypted = er->ecm[8] & 1;
            uchar cryptkey = (er->ecm[8] & 6) >> 1;

            if (crypted == 0)
            {
                cmdlen = 50;
            }
            else
            {
                cmdlen = 57;
            }

            uchar ecmcmd[cmdlen];

            memcpy(ecmcmd, &er->ecm[17], cmdlen-1);
            ecmcmd[cmdlen-1] = csystem_data->provider;

            dre_cmd_c(ecmcmd, crypted, cryptkey);

            if(cta_res[2] == 0xD2 && isValidDCW(cta_res + 3))
            {
                memcpy(ea->cw, cta_res+11, 8);
                memcpy(ea->cw+8, cta_res+3, 8);
                return OK;
            }
        }
    }
    else if(reader->caid == 0x2710 && er->ecm[3] == 4)
Exemple #22
0
static int32_t pcsc_init(struct s_reader *pcsc_reader)
{
	ULONG rv;
	DWORD dwReaders = 0;
	LPSTR mszReaders = NULL;
	char *ptr, **readers = NULL;
	char *device = pcsc_reader->device;
	int32_t nbReaders;
	int32_t reader_nb;

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC establish context for PCSC pcsc_reader %s", device);
	SCARDCONTEXT hContext;
	memset(&hContext, 0, sizeof(hContext));
	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
	if(rv == SCARD_S_SUCCESS)
	{
		if(!cs_malloc(&pcsc_reader->crdr_data, sizeof(struct pcsc_data)))
			{ return ERROR; }
		struct pcsc_data *crdr_data = pcsc_reader->crdr_data;
		crdr_data->hContext = hContext;

		// here we need to list the pcsc readers and get the name from there,
		// the pcsc_reader->device should contain the pcsc_reader number
		// and after the actual device name is copied in crdr_data->pcsc_name .
		rv = SCardListReaders(crdr_data->hContext, NULL, NULL, &dwReaders);
		if(rv != SCARD_S_SUCCESS)
		{
			rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC failed listing readers [1] : (%lx)", (unsigned long)rv);
			return ERROR;
		}
		if(!cs_malloc(&mszReaders, dwReaders))
			{ return ERROR; }
		rv = SCardListReaders(crdr_data->hContext, NULL, mszReaders, &dwReaders);
		if(rv != SCARD_S_SUCCESS)
		{
			rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC failed listing readers [2]: (%lx)", (unsigned long)rv);
			NULLFREE(mszReaders);
			return ERROR;
		}
		/* Extract readers from the null separated string and get the total
		 * number of readers
		 */
		nbReaders = 0;
		ptr = mszReaders;
		while(*ptr != '\0')
		{
			ptr += strlen(ptr) + 1;
			nbReaders++;
		}

		if(nbReaders == 0)
		{
			rdr_log(pcsc_reader, "PCSC : no pcsc_reader found");
			NULLFREE(mszReaders);
			return ERROR;
		}

		if(!cs_malloc(&readers, nbReaders * sizeof(char *)))
		{
			NULLFREE(mszReaders);
			return ERROR;
		}

		char* device_line;
		char* device_first;
		char* device_second;

		device_line = strdup((const char *)&pcsc_reader->device);
		device_first = strsep(&device_line, ":");
		device_second = strsep(&device_line, ":");
		reader_nb = atoi(device_first);

		/* fill the readers table */
		nbReaders = 0;
		ptr = mszReaders;
		while(*ptr != '\0')
		{
			rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC pcsc_reader %d: %s", nbReaders, ptr);
			readers[nbReaders] = ptr;
			if ((reader_nb == -1) && (device_second != NULL) && strstr(ptr,device_second)){
				reader_nb = nbReaders;
			}
			ptr += strlen(ptr) + 1;
			nbReaders++;
		}

		if(reader_nb < 0 || reader_nb >= nbReaders)
		{
			rdr_log(pcsc_reader, "Wrong pcsc_reader index: %d", reader_nb);
			NULLFREE(mszReaders);
			NULLFREE(readers);
			NULLFREE(device_line);
			return ERROR;
		}

		if (readers)
		{
		snprintf(crdr_data->pcsc_name, sizeof(crdr_data->pcsc_name), "%s", readers[reader_nb]);
		NULLFREE(readers);
		}
		NULLFREE(mszReaders);
		NULLFREE(device_line);
	}
	else
	{
		rdr_log(pcsc_reader, "PCSC failed establish context (%lx)", (unsigned long)rv);
		return ERROR;
	}
	return OK;
}