1 | /*
|
---|
2 | ifd_phoenix.c
|
---|
3 | This module provides IFD handling functions for Smartmouse/Phoenix reader.
|
---|
4 | */
|
---|
5 |
|
---|
6 | #include "../globals.h"
|
---|
7 |
|
---|
8 | #ifdef CARDREADER_PHOENIX
|
---|
9 | #include "../oscam-time.h"
|
---|
10 | #include "icc_async.h"
|
---|
11 | #include "ifd_db2com.h"
|
---|
12 | #include "ifd_phoenix.h"
|
---|
13 | #include "io_serial.h"
|
---|
14 |
|
---|
15 | #define OK 0
|
---|
16 | #define ERROR 1
|
---|
17 |
|
---|
18 | #define GPIO_PIN (1 << (reader->detect - 4))
|
---|
19 |
|
---|
20 | static inline int reader_use_gpio(struct s_reader * reader) {
|
---|
21 | return reader->use_gpio && reader->detect > 4;
|
---|
22 | }
|
---|
23 |
|
---|
24 | static void set_gpio(struct s_reader * reader, int32_t level)
|
---|
25 | {
|
---|
26 | int ret = 0;
|
---|
27 |
|
---|
28 | ret |= read(reader->gpio_outen, &reader->gpio, sizeof(reader->gpio));
|
---|
29 | reader->gpio |= GPIO_PIN;
|
---|
30 | ret |= write(reader->gpio_outen, &reader->gpio, sizeof(reader->gpio));
|
---|
31 |
|
---|
32 | ret |= read(reader->gpio_out, &reader->gpio, sizeof(reader->gpio));
|
---|
33 | if (level > 0)
|
---|
34 | reader->gpio |= GPIO_PIN;
|
---|
35 | else
|
---|
36 | reader->gpio &= ~GPIO_PIN;
|
---|
37 | ret |= write(reader->gpio_out, &reader->gpio, sizeof(reader->gpio));
|
---|
38 |
|
---|
39 | rdr_debug_mask(reader, D_IFD, "%s level: %d ret: %d", __func__, level, ret);
|
---|
40 | }
|
---|
41 |
|
---|
42 | static void set_gpio_input(struct s_reader * reader)
|
---|
43 | {
|
---|
44 | int ret = 0;
|
---|
45 | ret |= read(reader->gpio_outen, &reader->gpio, sizeof(reader->gpio));
|
---|
46 | reader->gpio &= ~GPIO_PIN;
|
---|
47 | ret |= write(reader->gpio_outen, &reader->gpio, sizeof(reader->gpio));
|
---|
48 | rdr_debug_mask(reader, D_IFD, "%s ret:%d", __func__, ret);
|
---|
49 | }
|
---|
50 |
|
---|
51 | static int32_t get_gpio(struct s_reader * reader)
|
---|
52 | {
|
---|
53 | int ret = 0;
|
---|
54 | set_gpio_input(reader);
|
---|
55 | ret = read(reader->gpio_in, &reader->gpio, sizeof(reader->gpio));
|
---|
56 | rdr_debug_mask(reader, D_IFD, "%s ok:%d ret:%d", __func__, reader->gpio & GPIO_PIN, ret);
|
---|
57 | if (reader->gpio & GPIO_PIN)
|
---|
58 | return OK;
|
---|
59 | else
|
---|
60 | return ERROR;
|
---|
61 | }
|
---|
62 |
|
---|
63 | int32_t Phoenix_Init (struct s_reader * reader)
|
---|
64 | {
|
---|
65 | // First set card in reset state, to not change any parameters while communication ongoing
|
---|
66 | IO_Serial_RTS_Set(reader);
|
---|
67 | if (reader->crdr.flush) IO_Serial_Flush(reader);
|
---|
68 |
|
---|
69 | // define reader->gpio number used for card detect and reset. ref to globals.h
|
---|
70 | if (reader_use_gpio(reader))
|
---|
71 | {
|
---|
72 | reader->gpio_outen = open("/dev/gpio/outen", O_RDWR);
|
---|
73 | reader->gpio_out = open("/dev/gpio/out", O_RDWR);
|
---|
74 | reader->gpio_in = open("/dev/gpio/in", O_RDWR);
|
---|
75 | rdr_debug_mask(reader, D_IFD, "init gpio_outen:%d gpio_out:%d gpio_in:%d",
|
---|
76 | reader->gpio_outen, reader->gpio_out, reader->gpio_in);
|
---|
77 | set_gpio_input(reader);
|
---|
78 | }
|
---|
79 |
|
---|
80 | rdr_debug_mask(reader, D_IFD, "Initializing reader type=%d", reader->typ);
|
---|
81 |
|
---|
82 | /* Default serial port settings */
|
---|
83 | if (reader->atr[0] == 0) {
|
---|
84 | if(IO_Serial_SetParams (reader, DEFAULT_BAUDRATE, 8, PARITY_EVEN, 2, NULL, NULL)) return ERROR;
|
---|
85 | if (reader->crdr.flush) IO_Serial_Flush(reader);
|
---|
86 | }
|
---|
87 | return OK;
|
---|
88 | }
|
---|
89 |
|
---|
90 | int32_t Phoenix_GetStatus (struct s_reader * reader, int32_t * status)
|
---|
91 | {
|
---|
92 | // detect card via defined reader->gpio
|
---|
93 | if (reader_use_gpio(reader)) {
|
---|
94 | *status = !get_gpio(reader);
|
---|
95 | return OK;
|
---|
96 | } else {
|
---|
97 | return IO_Serial_GetStatus(reader, status);
|
---|
98 | }
|
---|
99 | }
|
---|
100 |
|
---|
101 | int32_t Phoenix_Reset (struct s_reader * reader, ATR * atr)
|
---|
102 | {
|
---|
103 | rdr_debug_mask(reader, D_IFD, "Resetting card");
|
---|
104 | int32_t ret;
|
---|
105 | int32_t i;
|
---|
106 | unsigned char buf[ATR_MAX_SIZE];
|
---|
107 | int32_t parity[3] = {PARITY_EVEN, PARITY_ODD, PARITY_NONE};
|
---|
108 |
|
---|
109 | call (IO_Serial_SetBaudrate(reader, DEFAULT_BAUDRATE));
|
---|
110 |
|
---|
111 | for(i=0; i<3; i++) {
|
---|
112 | if (reader->crdr.flush) IO_Serial_Flush(reader);
|
---|
113 | if (reader->crdr.set_parity) IO_Serial_SetParity (reader, parity[i]);
|
---|
114 |
|
---|
115 | ret = ERROR;
|
---|
116 |
|
---|
117 | IO_Serial_Ioctl_Lock(reader, 1);
|
---|
118 | if (reader_use_gpio(reader))
|
---|
119 | set_gpio(reader, 0);
|
---|
120 | else
|
---|
121 | IO_Serial_RTS_Set(reader);
|
---|
122 |
|
---|
123 | cs_sleepms(50);
|
---|
124 |
|
---|
125 | // felix: set card reset hi (inactive)
|
---|
126 | if (reader_use_gpio(reader))
|
---|
127 | set_gpio_input(reader);
|
---|
128 | else
|
---|
129 | IO_Serial_RTS_Clr(reader);
|
---|
130 | cs_sleepms(50);
|
---|
131 | IO_Serial_Ioctl_Lock(reader, 0);
|
---|
132 |
|
---|
133 | int32_t n=0;
|
---|
134 | while(n<ATR_MAX_SIZE && !IO_Serial_Read(reader, 0, ATR_TIMEOUT, 1, buf+n))
|
---|
135 | n++;
|
---|
136 | if(n==0)
|
---|
137 | continue;
|
---|
138 | if (ATR_InitFromArray (atr, buf, n) != ERROR)
|
---|
139 | ret = OK;
|
---|
140 | // Succesfully retrieve ATR
|
---|
141 | if (ret == OK)
|
---|
142 | break;
|
---|
143 | }
|
---|
144 |
|
---|
145 | return ret;
|
---|
146 | }
|
---|
147 |
|
---|
148 | int32_t Phoenix_Close (struct s_reader * reader)
|
---|
149 | {
|
---|
150 | rdr_debug_mask(reader, D_IFD, "Closing phoenix device %s", reader->device);
|
---|
151 | if (reader_use_gpio(reader))
|
---|
152 | {
|
---|
153 | if (reader->gpio_outen > -1)
|
---|
154 | close(reader->gpio_outen);
|
---|
155 | if (reader->gpio_out > -1)
|
---|
156 | close(reader->gpio_out);
|
---|
157 | if (reader->gpio_in > -1)
|
---|
158 | close(reader->gpio_in);
|
---|
159 | }
|
---|
160 | IO_Serial_Close(reader);
|
---|
161 | return OK;
|
---|
162 | }
|
---|
163 |
|
---|
164 | /*
|
---|
165 | int32_t Phoenix_FastReset (struct s_reader * reader, int32_t delay)
|
---|
166 | {
|
---|
167 | IO_Serial_Ioctl_Lock(reader, 1);
|
---|
168 | if (reader_use_gpio(reader))
|
---|
169 | set_gpio(reader, 0);
|
---|
170 | else
|
---|
171 | IO_Serial_RTS_Set(reader);
|
---|
172 |
|
---|
173 | cs_sleepms(delay);
|
---|
174 |
|
---|
175 | // set card reset hi (inactive)
|
---|
176 | if (reader_use_gpio(reader))
|
---|
177 | set_gpio_input(reader);
|
---|
178 | else
|
---|
179 | IO_Serial_RTS_Clr(reader);
|
---|
180 |
|
---|
181 | IO_Serial_Ioctl_Lock(reader, 0);
|
---|
182 |
|
---|
183 | cs_sleepms(50);
|
---|
184 |
|
---|
185 | IO_Serial_Flush(reader);
|
---|
186 | return 0;
|
---|
187 |
|
---|
188 | }
|
---|
189 | */
|
---|
190 | static int32_t mouse_init(struct s_reader *reader) {
|
---|
191 | if (detect_db2com_reader(reader)) {
|
---|
192 | cardreader_db2com(&reader->crdr);
|
---|
193 | return reader->crdr.reader_init(reader);
|
---|
194 | }
|
---|
195 |
|
---|
196 | reader->handle = open (reader->device, O_RDWR | O_NOCTTY| O_NONBLOCK);
|
---|
197 | if (reader->handle < 0) {
|
---|
198 | rdr_log(reader, "ERROR: Opening device %s (errno=%d %s)",
|
---|
199 | reader->device, errno, strerror(errno));
|
---|
200 | return ERROR;
|
---|
201 | }
|
---|
202 | if (Phoenix_Init(reader)) {
|
---|
203 | rdr_log(reader, "ERROR: Phoenix_Init returns error");
|
---|
204 | Phoenix_Close (reader);
|
---|
205 | return ERROR;
|
---|
206 | }
|
---|
207 | return OK;
|
---|
208 | }
|
---|
209 |
|
---|
210 | void cardreader_mouse(struct s_cardreader *crdr)
|
---|
211 | {
|
---|
212 | crdr->desc = "mouse";
|
---|
213 | crdr->typ = R_MOUSE;
|
---|
214 | crdr->flush = 1;
|
---|
215 | crdr->read_written = 1;
|
---|
216 | crdr->need_inverse = 1;
|
---|
217 | crdr->reader_init = mouse_init;
|
---|
218 | crdr->get_status = Phoenix_GetStatus;
|
---|
219 | crdr->activate = Phoenix_Reset;
|
---|
220 | crdr->transmit = IO_Serial_Transmit;
|
---|
221 | crdr->receive = IO_Serial_Receive;
|
---|
222 | crdr->close = Phoenix_Close;
|
---|
223 | crdr->set_parity = IO_Serial_SetParity;
|
---|
224 | crdr->set_baudrate = IO_Serial_SetBaudrate;
|
---|
225 | }
|
---|
226 | #endif
|
---|