/* ifd_drecas.c This module provides IFD handling functions for DreCas reader. */ #include "../globals.h" #include "../oscam-string.h" #ifdef CARDREADER_DRECAS #include "../oscam-time.h" #include "icc_async.h" #include "ifd_drecas.h" #include "io_serial.h" #define OK 0 #define ERROR 1 int32_t DreCas_Init(struct s_reader *reader) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; if(crdr_ops->flush) { IO_Serial_Flush(reader); } rdr_log_dbg(reader, D_IFD, "Initializing reader type=%d", reader->typ); /* Default serial port settings */ if(reader->atr[0] == 0) { if(IO_Serial_SetParams(reader, DEFAULT_BAUDRATE, 8, PARITY_NONE, 1, NULL, NULL)) { return ERROR; } if(crdr_ops->flush) { IO_Serial_Flush(reader); } } return OK; } int32_t DreCas_GetStatus(struct s_reader *UNUSED(reader), int32_t *UNUSED(status)) { return OK; } int32_t DreCas_Reset(struct s_reader *reader, ATR *atr) { rdr_log_dbg(reader, D_IFD, "Resetting card"); rdr_log_dbg(reader, D_IFD, "DreCas_Reset"); int32_t ret; uint8_t buf[ATR_MAX_SIZE]; uint8_t reset_cmd[5] = { 0xDB ,0x03 ,0x00 ,0xC1 ,0xC1 }; if(IO_Serial_SetParams(reader, DEFAULT_BAUDRATE, 8, PARITY_NONE, 2, NULL, NULL)) { return ERROR; } const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; if(crdr_ops->flush) { IO_Serial_Flush(reader); } ret = ERROR; IO_Serial_Ioctl_Lock(reader, 1); /* Module soft reset */ IO_Serial_Write(reader, 0, 0, (uint32_t)sizeof(reset_cmd), reset_cmd); cs_sleepms(50); IO_Serial_Ioctl_Lock(reader, 0); int32_t n = 0; while(n < ATR_MAX_SIZE && !IO_Serial_Read(reader, 50, ATR_TIMEOUT, 1, buf + n)) { n++; } if(ATR_InitFromArray(atr, buf, n) != ERROR) { ret = OK; } return ret; } int32_t DreCas_Close(struct s_reader *reader) { rdr_log_dbg(reader, D_IFD, "Closing DreCas device %s", reader->device); IO_Serial_Close(reader); return OK; } static int32_t mouse_init(struct s_reader *reader) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; reader->handle = open(reader->device, O_RDWR | O_NOCTTY | O_NONBLOCK); if(reader->handle < 0) { rdr_log(reader, "ERROR: Opening device %s (errno=%d %s)", reader->device, errno, strerror(errno)); return ERROR; } if(DreCas_Init(reader)) { rdr_log(reader, "ERROR: DreCas_Init returns error"); DreCas_Close(reader); return ERROR; } return OK; } static int32_t DreCas_SetParity(struct s_reader *reader, unsigned char UNUSED(parity)) { return IO_Serial_SetParity(reader, PARITY_NONE); } const struct s_cardreader cardreader_drecas = { .desc = "drecas", .typ = R_DRECAS, .flush = 1, .read_written = 0, .need_inverse = 0, .reader_init = mouse_init, .get_status = DreCas_GetStatus, .activate = DreCas_Reset, .transmit = IO_Serial_Transmit, .receive = IO_Serial_Receive, .close = DreCas_Close, .set_parity = DreCas_SetParity, .set_baudrate = IO_Serial_SetBaudrate, }; #endif