- reduced binary size with AES constants, there was twice included (thanks to lpm11...
[oscam.git] / csctapi / ifd_db2com.c
blob1cdf8baaaae4c9520cd66c0fab2ee6db19ec83de
1 #include "../globals.h"
3 #ifdef CARDREADER_DB2COM
4 #include "../oscam-time.h"
5 #include "icc_async.h"
6 #include "ifd_phoenix.h"
7 #include "io_serial.h"
9 // Multicam defines
10 #define DEV_MULTICAM "/dev/multicam"
11 #define MULTICAM_GET_PCDAT 10
12 #define MULTICAM_SET_PCDAT 13
14 #define OK 0
15 #define ERROR 1
17 bool detect_db2com_reader(struct s_reader *reader)
19 struct stat sb;
20 if(stat(DEV_MULTICAM, &sb) == -1)
21 { return false; }
22 if(stat(reader->device, &sb) == 0)
24 if(S_ISCHR(sb.st_mode))
26 int32_t dev_major = major(sb.st_rdev);
27 int32_t dev_minor = minor(sb.st_rdev);
28 if(dev_major == 4 || dev_major == 5)
30 int32_t rc;
31 switch(dev_minor & 0x3F)
33 case 0:
34 rc = R_DB2COM1;
35 break;
36 case 1:
37 rc = R_DB2COM2;
38 break;
39 default:
40 return false;
42 reader->typ = rc;
44 rdr_log_dbg(reader, D_READER, "device is major: %d, minor: %d, typ=%d", dev_major, dev_minor, reader->typ);
47 return true;
50 static int32_t db2com_init(struct s_reader *reader)
52 if(reader->typ != R_DB2COM1 && reader->typ != R_DB2COM2)
53 { detect_db2com_reader(reader); }
55 reader->handle = open(reader->device, O_RDWR | O_NOCTTY | O_SYNC);
56 if(reader->handle < 0)
58 rdr_log(reader, "ERROR: Opening device %s (errno=%d %s)", reader->device, errno, strerror(errno));
59 return ERROR;
61 if((reader->fdmc = open(DEV_MULTICAM, O_RDWR)) < 0)
63 rdr_log(reader, "ERROR: Opening device %s (errno=%d %s)", DEV_MULTICAM, errno, strerror(errno));
64 close(reader->handle);
65 return ERROR;
67 if(Phoenix_Init(reader))
69 rdr_log(reader, "ERROR: Phoenix_Init returns error");
70 Phoenix_Close(reader);
71 return ERROR;
73 return OK;
76 static int32_t db2com_get_status(struct s_reader *reader, int32_t *status)
78 *status = 0;
79 uint16_t msr = 1;
80 IO_Serial_Ioctl_Lock(reader, 1);
81 ioctl(reader->fdmc, MULTICAM_GET_PCDAT, &msr);
82 if(reader->typ == R_DB2COM2)
83 { *status = !(msr & 1); }
84 else
85 { *status = (msr & 0x0f00) == 0x0f00; }
86 IO_Serial_Ioctl_Lock(reader, 0);
87 return OK;
90 static bool db2com_DTR_RTS(struct s_reader *reader, int32_t *dtr, int32_t *rts)
92 int32_t rc;
93 uint16_t msr;
94 uint16_t rts_bits[2] = { 0x10, 0x800 };
95 uint16_t dtr_bits[2] = {0x100, 0 };
96 int32_t mcport = reader->typ == R_DB2COM2;
98 rc = ioctl(reader->fdmc, MULTICAM_GET_PCDAT, &msr);
99 if(rc < 0)
100 { return ERROR; }
102 if(dtr)
104 rdr_log_dbg(reader, D_DEVICE, "%s DTR:%s", __func__, *dtr ? "set" : "clear");
105 if(dtr_bits[mcport])
107 if(*dtr)
108 { msr &= (uint16_t)(~dtr_bits[mcport]); }
109 else
110 { msr |= dtr_bits[mcport]; }
111 rc = ioctl(reader->fdmc, MULTICAM_SET_PCDAT, &msr);
113 else
115 rc = 0; // Dummy, can't handle using multicam.o
119 if(rts)
121 rdr_log_dbg(reader, D_DEVICE, "%s RTS:%s", __func__, *rts ? "set" : "clear");
122 if(*rts)
123 { msr &= (uint16_t)(~rts_bits[mcport]); }
124 else
125 { msr |= rts_bits[mcport]; }
126 rc = ioctl(reader->fdmc, MULTICAM_SET_PCDAT, &msr);
129 if(rc < 0)
130 { return ERROR; }
131 return OK;
134 const struct s_cardreader cardreader_db2com =
136 .desc = "db2com",
137 .typ = R_DB2COM1,
138 .flush = 1,
139 .need_inverse = 1,
140 .read_written = 1,
141 .reader_init = db2com_init,
142 .get_status = db2com_get_status,
143 .activate = Phoenix_Reset,
144 .transmit = IO_Serial_Transmit,
145 .receive = IO_Serial_Receive,
146 .close = Phoenix_Close,
147 .set_parity = IO_Serial_SetParity,
148 .set_baudrate = IO_Serial_SetBaudrate,
149 .set_DTS_RTS = db2com_DTR_RTS,
152 #endif