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_debug_mask(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); NULLFREE(reader->csystem_data); if (cl) { cl->lastemm = 0; cl->lastecm = 0; } led_status_card_ejected(); } reader->card_status = NO_CARD; } rdr_debug_mask(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; }
int32_t ICC_Async_Close (struct s_reader *reader) { rdr_debug_mask(reader, D_IFD, "Closing device %s", reader->device); call(reader->crdr.close(reader)); rdr_debug_mask(reader, D_IFD, "Device %s succesfully closed", reader->device); return OK; }
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 FALSE; } if(!cs_malloc(&reader->spec_dev,sizeof(struct s_coolstream_reader), -1)) return 0; if (cnxt_smc_open (&specdev()->handle, &reader_nb, NULL, NULL)) return FALSE; int32_t ret = cnxt_smc_enable_flow_control(specdev()->handle); 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 default init timeout (%i). If you encounter any problems while card init try to use the reader parameter cool_timeout_init = 500", READ_WRITE_TRANSMIT_TIMEOUT); specdev()->read_write_transmit_timeout = READ_WRITE_TRANSMIT_TIMEOUT; } return OK; }
static int32_t ICC_Async_GetPLL_Divider (struct s_reader * reader) { if(reader->divider != 0) return reader->divider; if(reader->mhz != 8300) /* Check dreambox is not DM7025 */ { float divider; divider = ((float) reader->mhz) / ((float) reader->cardmhz); reader->divider = (int32_t) divider; if(divider > reader->divider) reader->divider++; /* to prevent over clocking, ceil (round up) the divider */ rdr_debug_mask(reader, D_DEVICE,"PLL maxmhz = %.2f, wanted cardmhz = %.2f, divider used = %d, actualcardclock=%.2f", (float) reader->mhz/100, (float) reader->cardmhz/100, reader->divider, (float) reader->mhz/reader->divider/100); reader->cardmhz = reader->mhz/reader->divider; } else /* STB is DM7025 */ { int32_t i, dm7025_clock_freq[] = {518, 461, 395, 360, 319, 296, 267, 244, 230, 212, 197}, dm7025_PLL_setting[] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, t_cardmhz = reader->cardmhz; for(i = 0; i < 11; i++) if(t_cardmhz >= dm7025_clock_freq[i]) break; if(i > 10) i = 10; reader->cardmhz = dm7025_clock_freq[i]; reader->divider = dm7025_PLL_setting[i]; /*Nicer way of codeing is: reader->divider = i + 6;*/ rdr_debug_mask(reader, D_DEVICE,"DM7025 PLL maxmhz = %.2f, wanted cardmhz = %.2f, PLL setting used = %d, actualcardclock=%.2f", (float) reader->mhz/100, (float) t_cardmhz/100, reader->divider, (float) reader->cardmhz/100); } return reader->divider; }
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_debug_mask(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_debug_mask(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_debug_mask(pcsc_reader, D_DEVICE, "PCSC invalid protocol (T=%lu)", (unsigned long)crdr_data->dwActiveProtocol); return ERROR; } rdr_debug_mask(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_debug_mask(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; } }
int32_t Cool_Set_Transmit_Timeout(struct s_reader *reader, uint32_t set) { //set=0 (init), set=1(after init) if (set) { if (reader->cool_timeout_after_init > 0) { specdev()->read_write_transmit_timeout = reader->cool_timeout_after_init; rdr_debug_mask(reader, D_DEVICE, "timeout set to cool_timeout_after_init = %i", reader->cool_timeout_after_init); } else { if (reader->read_timeout > 50) { rdr_log(reader, "ATTENTION: The calculated timeout after init value (%i) is greater than 50 which probably leads to a slow card response. We are going to use the reader parameter cool_timeout_after_init = 50.", reader->read_timeout); rdr_log(reader, "If you encounter any problems try a higher value. If you have no problems try a value below to get a faster card response."); specdev()->read_write_transmit_timeout = 50; } else { rdr_debug_mask(reader, D_DEVICE, "no timeout specified - using calculated timeout after init (%i)", reader->read_timeout); specdev()->read_write_transmit_timeout = reader->read_timeout; } } } else { if (reader->cool_timeout_init > 0) { specdev()->read_write_transmit_timeout = reader->cool_timeout_init; } else { specdev()->read_write_transmit_timeout = READ_WRITE_TRANSMIT_TIMEOUT; } } return OK; }
int32_t IO_Serial_SetParity (struct s_reader * reader, unsigned char parity) { struct termios tio; int32_t current_parity; // Get current parity if (tcgetattr (reader->handle, &tio) != 0){ rdr_log(reader, "ERROR: Could not get current parity, %s (errno=%d %s)", __func__, errno, strerror(errno)); current_parity = 5; // set to unknown (5 is not predefined!) } else { if (((tio.c_cflag) & PARENB) == PARENB) { if (((tio.c_cflag) & PARODD) == PARODD) current_parity = PARITY_ODD; else current_parity = PARITY_EVEN; } else { current_parity = PARITY_NONE; } } if (current_parity != parity) { rdr_debug_mask(reader, D_IFD, "Setting parity from %s to %s", current_parity == PARITY_ODD ? "Odd" : current_parity == PARITY_NONE ? "None" : current_parity == PARITY_EVEN ? "Even" : "Unknown", parity == PARITY_ODD ? "Odd" : parity == PARITY_NONE ? "None" : parity == PARITY_EVEN ? "Even" : "Invalid"); // Set the parity switch (parity) { case PARITY_ODD: tio.c_cflag |= PARENB; tio.c_cflag |= PARODD; break; case PARITY_EVEN: tio.c_cflag |= PARENB; tio.c_cflag &= ~PARODD; break; case PARITY_NONE: tio.c_cflag &= ~PARENB; break; } if (IO_Serial_SetProperties (reader, tio)){ rdr_debug_mask(reader, D_IFD, "ERROR: could set parity!"); return ERROR; } } return OK; }
int32_t ICC_Async_Close(struct s_reader *reader) { rdr_debug_mask(reader, D_IFD, "Closing device %s", reader->device); call(reader->crdr.close(reader)); if(reader->typ != R_SC8in1) { NULLFREE(reader->crdr_data); } rdr_debug_mask(reader, D_IFD, "Device %s succesfully closed", reader->device); return OK; }
bool IO_Serial_SetBitrate (struct s_reader * reader, uint32_t bitrate, struct termios * tio) { /* Set the bitrate */ #if defined(__linux__) //FIXME workaround for Smargo until native mode works if ((reader->mhz == reader->cardmhz) && (reader->smargopatch != 1) && IO_Serial_Bitrate(bitrate) != B0) #else if(IO_Serial_Bitrate(bitrate) == B0) { rdr_log(reader, "Baudrate %u not supported", bitrate); return ERROR; } else #endif { //no overclocking cfsetospeed(tio, IO_Serial_Bitrate(bitrate)); cfsetispeed(tio, IO_Serial_Bitrate(bitrate)); rdr_debug_mask(reader, D_DEVICE, "standard baudrate: cardmhz=%d mhz=%d -> effective baudrate %u", reader->cardmhz, reader->mhz, bitrate); } #if defined(__linux__) else { //over or underclocking /* these structures are only available on linux */ struct serial_struct nuts; // This makes valgrind happy, because it doesn't know what TIOCGSERIAL does // Without this there are lots of misleading errors of type: // "Conditional jump or move depends on uninitialised value(s)" nuts.baud_base = 0; nuts.custom_divisor = 0; ioctl(reader->handle, TIOCGSERIAL, &nuts); int32_t custom_baud_asked = bitrate * reader->mhz / reader->cardmhz; nuts.custom_divisor = (nuts.baud_base + (custom_baud_asked/2))/ custom_baud_asked; int32_t custom_baud_delivered = nuts.baud_base / nuts.custom_divisor; rdr_debug_mask(reader, D_DEVICE, "custom baudrate: cardmhz=%d mhz=%d custom_baud=%d baud_base=%d divisor=%d -> effective baudrate %d", reader->cardmhz, reader->mhz, custom_baud_asked, nuts.baud_base, nuts.custom_divisor, custom_baud_delivered); int32_t baud_diff = custom_baud_delivered - custom_baud_asked; if (baud_diff < 0) baud_diff = (-baud_diff); if (baud_diff > 0.05 * custom_baud_asked) { rdr_log(reader, "WARNING: your card is asking for custom_baudrate = %i, but your configuration can only deliver custom_baudrate = %i",custom_baud_asked, custom_baud_delivered); rdr_log(reader, "You are over- or underclocking, try OSCam when running your reader at normal clockspeed as required by your card, and setting mhz and cardmhz parameters accordingly."); if (nuts.baud_base <= 115200) rdr_log(reader, "You are probably connecting your reader via a serial port, OSCam has more flexibility switching to custom_baudrates when using an USB->serial converter, preferably based on FTDI chip."); } nuts.flags &= ~ASYNC_SPD_MASK; nuts.flags |= ASYNC_SPD_CUST; ioctl(reader->handle, TIOCSSERIAL, &nuts); cfsetospeed(tio, IO_Serial_Bitrate(38400)); cfsetispeed(tio, IO_Serial_Bitrate(38400)); } #endif if (reader->typ == R_SC8in1) { reader->sc8in1_config->current_baudrate = bitrate; } return OK; }
int32_t ICC_Async_Receive(struct s_reader *reader, uint32_t size, unsigned char *data, uint32_t delay, uint32_t timeout) { rdr_debug_mask(reader, D_IFD, "Receive size %d bytes, delay %d us, timeout=%d us", size, delay, timeout); call(reader->crdr.receive(reader, data, size, delay, timeout)); rdr_debug_mask(reader, D_IFD, "Receive succesful"); if(reader->convention == ATR_CONVENTION_INVERSE && reader->crdr.need_inverse == 1) { ICC_Async_InvertBuffer(size, data); } return OK; }
bool IO_Serial_Write (struct s_reader * reader, uint32_t delay, uint32_t timeout, uint32_t size, const unsigned char * data) { if (timeout == 0){ // General fix for readers not communicating timeout and delay if (reader->char_delay != 0) timeout = reader->char_delay; else timeout = 1000000; rdr_debug_mask(reader, D_DEVICE,"Warning: write timeout 0 changed to %d us", timeout); } uint32_t count, to_send, i_w; unsigned char data_w[512]; to_send = (delay? 1: size); // calculate chars to send at one rdr_debug_mask(reader, D_DEVICE,"Write timeout %d us, write delay %d us, to send %d char(s), chunksize %d char(s)", timeout, delay, size, to_send); for (count = 0; count < size; count += to_send) { if (count + to_send > size){ to_send = size - count; } uint16_t errorcount=0, to_do=to_send; for (i_w=0; i_w < to_send; i_w++) data_w [i_w] = data [count + i_w]; rdr_ddump_mask(reader, D_DEVICE, data_w+(to_send-to_do), to_do, "Sending:"); AGAIN: if (!IO_Serial_WaitToWrite (reader, delay, timeout)) { while (to_do !=0){ int32_t u = write (reader->handle, data_w+(to_send-to_do), to_do); if (u < 1) { if (errno==EINTR) continue; //try again in case of Interrupted system call if (errno==EAGAIN) goto AGAIN; //EAGAIN needs a select procedure again errorcount++; int16_t written = count + to_send - to_do; if (u != 0) { rdr_log(reader, "ERROR: %s: Written=%d of %d (errno=%d %s)", __func__, written , size, errno, strerror(errno)); } if (errorcount > 10){ //exit if more than 10 errors return ERROR; } } else { to_do -= u; errorcount = 0; if (reader->crdr.read_written) reader->written += u; // these readers echo transmitted chars } } } else { rdr_log(reader, "Timeout in IO_Serial_WaitToWrite, delay=%d us, timeout=%d us", delay, timeout); return ERROR; } } return OK; }
int32_t ICC_Async_Device_Init (struct s_reader *reader) { reader->fdmc=-1; rdr_debug_mask(reader, D_IFD, "Opening device %s", reader->device); reader->written = 0; int32_t ret = reader->crdr.reader_init(reader); if (ret == OK) rdr_debug_mask(reader, D_IFD, "Device %s succesfully opened", reader->device); else rdr_debug_mask(reader, D_IFD, "ERROR: Can't open %s device", reader->device); return ret; }
int32_t ICC_Async_Activate(struct s_reader *reader, ATR *atr, uint16_t deprecated) { rdr_debug_mask(reader, D_IFD, "Activating card"); reader->current_baudrate = DEFAULT_BAUDRATE; if(reader->atr[0] != 0 && !reader->ins7e11_fast_reset) { rdr_log(reader, "Using ATR from reader config"); ATR_InitFromArray(atr, reader->atr, ATR_MAX_SIZE); } else { call(reader->crdr.activate(reader, atr)); if(reader->crdr.skip_extra_atr_parsing) { return OK; } } unsigned char atrarr[ATR_MAX_SIZE]; uint32_t atr_size; ATR_GetRaw(atr, atrarr, &atr_size); char tmp[atr_size * 3 + 1]; rdr_log(reader, "ATR: %s", cs_hexdump(1, atrarr, atr_size, tmp, sizeof(tmp))); memcpy(reader->card_atr, atrarr, atr_size); reader->card_atr_length = atr_size; /* Get ICC reader->convention */ if(ATR_GetConvention(atr, &(reader->convention)) != ATR_OK) { rdr_log(reader, "ERROR: Could not read reader->convention"); reader->convention = 0; reader->protocol_type = 0; return ERROR; } reader->protocol_type = ATR_PROTOCOL_TYPE_T0; // Parse_ATR and InitCard need to be included in lock because they change parity of serial port if(reader->crdr.lock) { reader->crdr.lock(reader); } int32_t ret = Parse_ATR(reader, atr, deprecated); if(reader->crdr.unlock) { reader->crdr.unlock(reader); } if(ret) { rdr_log(reader, "ERROR: Parse_ATR returned error"); } if(ret) { return ERROR; } rdr_debug_mask(reader, D_IFD, "Card succesfully activated"); return OK; }
int32_t reader_do_emm(struct s_reader * reader, EMM_PACKET *ep) { int32_t i, rc, ecs; unsigned char md5tmp[MD5_DIGEST_LENGTH]; struct timeb tps; struct s_client *cl = reader->client; if(!cl) return 0; cs_ftime(&tps); MD5(ep->emm, ep->emm[2], md5tmp); for (i = ecs = 0; i < CS_EMMCACHESIZE; i++) { if (!memcmp(cl->emmcache[i].emmd5, md5tmp, CS_EMMSTORESIZE)) { cl->emmcache[i].count++; if (reader->cachemm) { if (cl->emmcache[i].count > reader->rewritemm) { ecs = 2; //skip emm } else { ecs = 1; //rewrite emm } } break; } } // Ecs=0 not found in cache // Ecs=1 found in cache, rewrite emm // Ecs=2 skip if ((rc = ecs) < 2) { if (is_cascading_reader(reader)) { rdr_debug_mask(reader, D_READER, "network emm reader"); if (reader->ph.c_send_emm) { rc = reader->ph.c_send_emm(ep); } else { rdr_debug_mask(reader, D_READER, "send_emm() support missing"); rc = 0; } } else { rdr_debug_mask(reader, D_READER, "local emm reader"); rc = cardreader_do_emm(reader, ep); } if (!ecs) i = reader_store_emm(ep->type, md5tmp); } reader_log_emm(reader, ep, i, rc, &tps); return rc; }
static int32_t Azbox_Init(struct s_reader *reader) { rdr_debug_mask(reader, D_DEVICE, "openxcas sc: init"); if ((reader->handle = openxcas_get_smartcard_device(0)) < 0) { rdr_debug_mask(reader, D_DEVICE, "openxcas sc: init failed (%d)", reader->handle); return 0; } rdr_debug_mask(reader, D_DEVICE, "openxcas sc: init succeeded"); return OK; }
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]; 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] = reader->provider; memcpy (ecmcmd41 + 4, er->ecm + 8, 16); ecmcmd41[20] = er->ecm[6]; //keynumber ecmcmd41[21] = 0x58 + er->ecm[25]; //package number rdr_debug_mask(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg))); rdr_debug_mask(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_debug_mask(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg))); rdr_debug_mask(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg))); ecmcmd51[33] = reader->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; }
void cardreader_process_ecm(struct s_reader *reader, struct s_client *cl, ECM_REQUEST *er) { if (ecm_ratelimit_check(reader, er, 1) != OK) { rdr_debug_mask(reader, D_READER, "%s: ratelimit check failed.", __func__); return; // reader_mode = 1: checkout ratelimiter in reader mode so srvid can be replaced } cs_ddump_mask(D_ATR, er->ecm, er->ecmlen, "ecm:"); struct timeb tps, tpe; cs_ftime(&tps); struct s_ecm_answer ea; memset(&ea, 0, sizeof(struct s_ecm_answer)); int32_t rc = cardreader_do_ecm(reader, er, &ea); rdr_debug_mask(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[32]; rdr_debug_mask(reader, D_READER, "Error processing ecm for caid %04X, srvid %04X, servicename: %s", er->caid, er->srvid, get_servicename(cl, er->srvid, er->caid, buf)); ea.rc = E_NOTFOUND; ea.rcEx = 0; ICC_Async_DisplayMsg(reader, "Eer"); } if (rc == E_CORRUPT) { char buf[32]; rdr_debug_mask(reader, D_READER, "Error processing ecm for caid %04X, srvid %04X, servicename: %s", er->caid, er->srvid, get_servicename(cl, er->srvid, er->caid, buf)); ea.rc = E_NOTFOUND; ea.rcEx = E2_WRONG_CHKSUM; //flag it as wrong checksum memcpy (ea.msglog,"Invalid ecm type for card",25); } cs_ftime(&tpe); cl->lastecm=time((time_t*)0); char ecmd5[17*3]; cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5)); rdr_debug_mask(reader, D_READER, "ecm hash: %s real time: %ld ms", ecmd5, 1000 * (tpe.time - tps.time) + tpe.millitm - tps.millitm); write_ecm_answer(reader, er, ea.rc, ea.rcEx, ea.cw, ea.msglog); reader_post_process(reader); }
bool IO_Serial_DTR_RTS(struct s_reader * reader, int32_t * dtr, int32_t * rts) { if (reader->crdr.set_DTS_RTS) return reader->crdr.set_DTS_RTS(reader, dtr, rts); uint32_t msr; uint32_t mbit; if(dtr) { mbit = TIOCM_DTR; #if defined(TIOCMBIS) && defined(TIOBMBIC) if (ioctl (reader->handle, *dtr ? TIOCMBIS : TIOCMBIC, &mbit) < 0) return ERROR; #else if (ioctl(reader->handle, TIOCMGET, &msr) < 0) return ERROR; if (*dtr) msr|=mbit; else msr&=~mbit; if (ioctl(reader->handle, TIOCMSET, &msr)<0) return ERROR; #endif rdr_debug_mask(reader, D_DEVICE, "Setting %s=%i", "DTR", *dtr); } if(rts) { mbit = TIOCM_RTS; #if defined(TIOCMBIS) && defined(TIOBMBIC) if (ioctl (reader->handle, *rts ? TIOCMBIS : TIOCMBIC, &mbit) < 0) return ERROR; #else if (ioctl(reader->handle, TIOCMGET, &msr) < 0) return ERROR; if (*rts) msr|=mbit; else msr&=~mbit; if (ioctl(reader->handle, TIOCMSET, &msr)<0) return ERROR; #endif rdr_debug_mask(reader, D_DEVICE, "Setting %s=%i", "RTS", *rts); } return OK; }
static int32_t reader_device_type(struct s_reader * reader) { int32_t rc=reader->typ; struct stat sb; if (reader->typ == R_MOUSE) { if (!stat(reader->device, &sb)) { if (S_ISCHR(sb.st_mode)) { int32_t dev_major, dev_minor; dev_major=major(sb.st_rdev); dev_minor=minor(sb.st_rdev); if (((dev_major==4) || (dev_major==5))) switch(dev_minor & 0x3F) { case 0: rc=R_DB2COM1; break; case 1: rc=R_DB2COM2; break; } rdr_debug_mask(reader, D_READER, "device is major: %d, minor: %d, typ=%d", dev_major, dev_minor, rc); } } } reader->typ = rc; return(rc); }
static int32_t bulcrypt_get_emm_type(EMM_PACKET *ep, struct s_reader *reader) { char dump_emm_sn[64]; int32_t emm_len = check_sct_len(ep->emm, 3); memset(ep->hexserial, 0, 8); if (emm_len < 176) { rdr_debug_mask(reader, D_TRACE | D_EMM, "emm_len < 176 (%u): %s", emm_len, cs_hexdump(1, ep->emm, 12, dump_emm_sn, sizeof(dump_emm_sn))); ep->type = UNKNOWN; return 0; } uint8_t mask_last = 0x00; ep->type = UNKNOWN; switch (ep->emm[0]) { case BULCRYPT_EMM_UNIQUE_82: ep->type = UNIQUE; mask_last = 0xF0; break; // Bulsatcom case BULCRYPT_EMM_UNIQUE_8a: ep->type = UNIQUE; mask_last = 0xF0; break; // Polaris case BULCRYPT_EMM_UNIQUE_85: ep->type = UNIQUE; mask_last = 0x00; break; // Bulsatcom case BULCRYPT_EMM_UNIQUE_8b: ep->type = UNIQUE; mask_last = 0x00; break; // Polaris case BULCRYPT_EMM_SHARED_84: ep->type = SHARED; break; } bool ret = false; if (ep->type == UNIQUE) { // The serial numbers looks like this: // aa bb cc dd // To match EMM_82 and EMM_8a serial we compare (mask_last == 0xf0): // aa bb cc d- // To match EMM_85 and EMM_8b serial we compare (mask_last == 0x00): // aa bb cc -- memcpy(ep->hexserial, ep->emm + 3, 4); ret = reader->hexserial[0] == ep->hexserial[0] && reader->hexserial[1] == ep->hexserial[1] && reader->hexserial[2] == ep->hexserial[2] && ((reader->hexserial[3] & mask_last) == (ep->hexserial[3] & mask_last)); } else if (ep->type == SHARED) { // To match EMM_84 // aa bb -- -- memcpy(ep->hexserial, ep->emm + 3, 2); ret = reader->hexserial[0] == ep->hexserial[0] && reader->hexserial[1] == ep->hexserial[1]; } if (ret) { char dump_card_sn[64]; cs_hexdump(1, reader->hexserial, 4, dump_card_sn, sizeof(dump_card_sn)); cs_hexdump(1, ep->hexserial, 4, dump_emm_sn, sizeof(dump_emm_sn)); rdr_log_sensitive(reader, "EMM_%s-%02x, emm_sn = {%s}, card_sn = {%s}", ep->type == UNIQUE ? "UNIQUE" : ep->type == SHARED ? "SHARED" : "??????", ep->emm[0], dump_emm_sn, dump_card_sn); } return ret; }
int32_t Cool_Reset (struct s_reader *reader, ATR * atr) { //set freq to reader->cardmhz if necessary uint32_t clk; int32_t ret; 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)); } //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 = 40; unsigned char buf[40]; 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; } }
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_debug_mask(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; }
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_debug_mask(reader, D_READER, "device is major: %d, minor: %d, typ=%d", dev_major, dev_minor, reader->typ); } } return true; }
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; }
void pcsc_close(struct s_reader *pcsc_reader) { rdr_debug_mask(pcsc_reader, D_IFD, "PCSC : Closing device %s", pcsc_reader->device); SCardDisconnect((SCARDHANDLE)(pcsc_reader->hCard),SCARD_LEAVE_CARD); SCardReleaseContext(pcsc_reader->hContext); pcsc_reader->hCard=0; pcsc_reader->pcsc_has_card=0; }
static int32_t pcsc_close(struct s_reader *pcsc_reader) { struct pcsc_data *crdr_data = pcsc_reader->crdr_data; rdr_debug_mask(pcsc_reader, D_IFD, "PCSC : Closing device %s", pcsc_reader->device); SCardDisconnect(crdr_data->hCard, SCARD_LEAVE_CARD); SCardReleaseContext(crdr_data->hContext); return OK; }
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_debug_mask(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; }
static int32_t mp35_close(struct s_reader *reader) { rdr_debug_mask(reader, D_IFD, "Closing MP35 device %s", reader->device); IO_Serial_DTR_Clr(reader); IO_Serial_Close(reader); return OK; }
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; }
bool IO_Serial_SetProperties (struct s_reader * reader, struct termios newtio) { if(reader->typ == R_INTERNAL) return OK; if (tcsetattr (reader->handle, TCSANOW, &newtio) < 0) // set terminal attributes. return ERROR; int32_t mctl; rdr_debug_mask(reader, D_DEVICE, "Getting readerstatus..."); if (ioctl (reader->handle, TIOCMGET, &mctl) >= 0) { // get reader statusbits mctl &= ~TIOCM_RTS; rdr_debug_mask(reader, D_DEVICE, "Set reader ready to Send"); ioctl (reader->handle, TIOCMSET, &mctl); // set reader ready to send. } else rdr_log(reader, "WARNING: Cant get readerstatus!"); return OK; }