oscam-2.26.01-11942-802-wit.../csctapi/ifd_db2com.c

153 lines
3.4 KiB
C

#include "../globals.h"
#ifdef CARDREADER_DB2COM
#include "../oscam-time.h"
#include "icc_async.h"
#include "ifd_phoenix.h"
#include "io_serial.h"
// Multicam defines
#define DEV_MULTICAM "/dev/multicam"
#define MULTICAM_GET_PCDAT 10
#define MULTICAM_SET_PCDAT 13
#define OK 0
#define ERROR 1
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;
}
static int32_t db2com_init(struct s_reader *reader)
{
if(reader->typ != R_DB2COM1 && reader->typ != R_DB2COM2)
{ detect_db2com_reader(reader); }
reader->handle = open(reader->device, O_RDWR | O_NOCTTY | O_SYNC);
if(reader->handle < 0)
{
rdr_log(reader, "ERROR: Opening device %s (errno=%d %s)", reader->device, errno, strerror(errno));
return ERROR;
}
if((reader->fdmc = open(DEV_MULTICAM, O_RDWR)) < 0)
{
rdr_log(reader, "ERROR: Opening device %s (errno=%d %s)", DEV_MULTICAM, errno, strerror(errno));
close(reader->handle);
return ERROR;
}
if(Phoenix_Init(reader))
{
rdr_log(reader, "ERROR: Phoenix_Init returns error");
Phoenix_Close(reader);
return ERROR;
}
return OK;
}
static int32_t db2com_get_status(struct s_reader *reader, int32_t *status)
{
*status = 0;
uint16_t msr = 1;
IO_Serial_Ioctl_Lock(reader, 1);
ioctl(reader->fdmc, MULTICAM_GET_PCDAT, &msr);
if(reader->typ == R_DB2COM2)
{ *status = !(msr & 1); }
else
{ *status = (msr & 0x0f00) == 0x0f00; }
IO_Serial_Ioctl_Lock(reader, 0);
return OK;
}
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;
}
const struct s_cardreader cardreader_db2com =
{
.desc = "db2com",
.typ = R_DB2COM1,
.flush = 1,
.need_inverse = 1,
.read_written = 1,
.reader_init = db2com_init,
.get_status = db2com_get_status,
.activate = Phoenix_Reset,
.transmit = IO_Serial_Transmit,
.receive = IO_Serial_Receive,
.close = Phoenix_Close,
.set_parity = IO_Serial_SetParity,
.set_baudrate = IO_Serial_SetBaudrate,
.set_DTS_RTS = db2com_DTR_RTS,
};
#endif