153 lines
3.4 KiB
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
|