1 | #include "globals.h"
|
---|
2 | #include "reader/common.h"
|
---|
3 |
|
---|
4 | #include "reader/serial.h"
|
---|
5 |
|
---|
6 | #include "CAM/common.h"
|
---|
7 |
|
---|
8 | #include "simples.h"
|
---|
9 | #include "log.h"
|
---|
10 |
|
---|
11 | #include <signal.h>
|
---|
12 | #include <stdio.h>
|
---|
13 | #include <time.h>
|
---|
14 |
|
---|
15 | static void reader_common_clear_memory(struct s_reader *reader)
|
---|
16 | {
|
---|
17 | reader->online = 0;
|
---|
18 | reader->card_status = 0;
|
---|
19 | reader->card_system = 0;
|
---|
20 | memset(reader->card_atr, 0, sizeof (reader->card_atr));
|
---|
21 | reader->card_atr_size = 0;
|
---|
22 |
|
---|
23 | memset(reader->hexserial, 0, sizeof (reader->hexserial));
|
---|
24 | memset(reader->prid, 0xFF, sizeof (reader->prid));
|
---|
25 | memset(reader->caid, 0, sizeof (reader->caid));
|
---|
26 | memset(reader->availkeys, 0, sizeof (reader->availkeys));
|
---|
27 | reader->acs = 0;
|
---|
28 | reader->nprov = 0;
|
---|
29 |
|
---|
30 | client[cs_idx].lastemm = 0;
|
---|
31 | client[cs_idx].lastecm = 0;
|
---|
32 | client[cs_idx].au = -1;
|
---|
33 | }
|
---|
34 |
|
---|
35 | static int reader_common_card_is_inserted(struct s_reader *reader)
|
---|
36 | {
|
---|
37 | int rc = 0;
|
---|
38 |
|
---|
39 | /* Check that we don't have "disabled" this reader */
|
---|
40 | char filename[255];
|
---|
41 | if (strrchr (reader->device, '/')) {
|
---|
42 | snprintf(filename, sizeof(filename), "%sdisable-%s", cs_confdir, strrchr(reader->device, '/')+1);
|
---|
43 | if (file_exists(filename)) return 0;
|
---|
44 | }
|
---|
45 | snprintf(filename, sizeof(filename), "%sdisable-%s", cs_confdir, reader->label);
|
---|
46 | if (file_exists(filename)) return 0;
|
---|
47 |
|
---|
48 | if ((reader->type & R_IS_SERIAL) != 0) {
|
---|
49 | rc = reader_serial_card_is_inserted();
|
---|
50 | }
|
---|
51 |
|
---|
52 | return rc;
|
---|
53 | }
|
---|
54 |
|
---|
55 | static int reader_common_get_atr(struct s_reader *reader)
|
---|
56 | {
|
---|
57 | int rc = 0;
|
---|
58 |
|
---|
59 | if ((reader->type & R_IS_SERIAL) != 0) {
|
---|
60 | rc = reader_serial_get_atr(reader->card_atr, &reader->card_atr_size);
|
---|
61 | }
|
---|
62 |
|
---|
63 | if (rc) {
|
---|
64 | log_normal("Reader: ATR = %s", cs_hexdump(1, reader->card_atr, reader->card_atr_size));
|
---|
65 | }
|
---|
66 |
|
---|
67 | return rc;
|
---|
68 | }
|
---|
69 |
|
---|
70 | static int reader_common_get_bitrates(struct s_reader *reader)
|
---|
71 | {
|
---|
72 | int rc = 0;
|
---|
73 | unsigned long reader_bitrate_optimal;
|
---|
74 | unsigned long reader_bitrate_effective;
|
---|
75 |
|
---|
76 | if ((reader->type & R_IS_SERIAL) != 0) {
|
---|
77 | rc = reader_serial_get_bitrates(&reader_bitrate_optimal, &reader_bitrate_effective);
|
---|
78 | }
|
---|
79 |
|
---|
80 | if (rc) {
|
---|
81 | if (reader_bitrate_effective == reader_bitrate_optimal) {
|
---|
82 | log_normal("Reader: Using optimal bitrate of %lu bit/s", reader_bitrate_optimal);
|
---|
83 | } else {
|
---|
84 | log_normal("Reader: Using approximate bitrate of %lu bit/s", reader_bitrate_effective);
|
---|
85 | log_normal("Reader: Optimal bitrate is %lu bit/s (%+.2f%% off)", reader_bitrate_optimal, (((double) reader_bitrate_effective) - reader_bitrate_optimal) / reader_bitrate_optimal * 100);
|
---|
86 | }
|
---|
87 | }
|
---|
88 |
|
---|
89 | return rc;
|
---|
90 | }
|
---|
91 |
|
---|
92 | static int reader_common_init_card(struct s_reader *reader)
|
---|
93 | {
|
---|
94 | /* Get Answer to Reset from card */
|
---|
95 | if (!reader_common_get_atr(reader)) {
|
---|
96 | return 0;
|
---|
97 | }
|
---|
98 |
|
---|
99 | /* Show some information about bitrate */
|
---|
100 | if (!reader_common_get_bitrates(reader)) {
|
---|
101 | return 0;
|
---|
102 | }
|
---|
103 |
|
---|
104 | /* Detect the card system */
|
---|
105 | if (!cam_common_detect(reader->card_atr, reader->card_atr_size)) {
|
---|
106 | return 0;
|
---|
107 | }
|
---|
108 |
|
---|
109 | /* Load information from card */
|
---|
110 | reader_common_load_card(reader);
|
---|
111 |
|
---|
112 | return 1;
|
---|
113 | }
|
---|
114 |
|
---|
115 | int reader_common_init(struct s_reader *reader)
|
---|
116 | {
|
---|
117 | int rc = 0;
|
---|
118 | if ((reader->type & R_IS_SERIAL) != 0) {
|
---|
119 | rc = reader_serial_init(reader);
|
---|
120 | log_normal("Reader: Initialized serial reader %s (%s @ %2.2f Mhz %s%s)", reader->label, reader->device, (float) reader->frequency / 1000000, reader->detect & 0x80 ? "!" : "", RDR_CD_TXT[reader->detect & 0x7f]);
|
---|
121 | }
|
---|
122 |
|
---|
123 | return rc;
|
---|
124 | }
|
---|
125 |
|
---|
126 | void reader_common_load_card(struct s_reader *reader)
|
---|
127 | {
|
---|
128 | reader_common_check_health(reader);
|
---|
129 |
|
---|
130 | if (reader->card_status == CARD_INSERTED) {
|
---|
131 | /* Disable the reader if it was already online */
|
---|
132 | reader->online = 0;
|
---|
133 |
|
---|
134 | client[cs_idx].last = time((time_t) 0);
|
---|
135 |
|
---|
136 | /* Ask the CAM to load the card information */
|
---|
137 | if (cam_common_load_card()) {
|
---|
138 | /* Mark the reader as online */
|
---|
139 | reader->online = 1;
|
---|
140 |
|
---|
141 | log_normal("Reader: Ready for requests (%s)", reader->label);
|
---|
142 | }
|
---|
143 | }
|
---|
144 | }
|
---|
145 |
|
---|
146 | void reader_common_check_health(struct s_reader *reader)
|
---|
147 | {
|
---|
148 | /* Check if there is a card inserted in the reader */
|
---|
149 | if (reader_common_card_is_inserted(reader)) {
|
---|
150 | /* Check if card was just inserted */
|
---|
151 | if ((reader->card_status & CARD_INSERTED) == 0) {
|
---|
152 | reader->card_status = CARD_INSERTED;
|
---|
153 | log_normal("Reader: Card detected in %s", reader->label);
|
---|
154 |
|
---|
155 | /* Try to initialize the card */
|
---|
156 | if (!reader_common_init_card(reader)) {
|
---|
157 | reader->card_status |= CARD_FAILURE;
|
---|
158 | log_normal("Reader: Cannot initialize card in %s !", reader->label);
|
---|
159 | } else {
|
---|
160 | client[cs_idx].au = ridx;
|
---|
161 | }
|
---|
162 |
|
---|
163 | /* ? */
|
---|
164 | int i;
|
---|
165 | for (i = 1; i < CS_MAXPID; i++) {
|
---|
166 | if (client[i].pid && client[i].typ == 'c' && client[i].usr[0]) {
|
---|
167 | kill(client[i].pid, SIGQUIT);
|
---|
168 | }
|
---|
169 | }
|
---|
170 | }
|
---|
171 | } else {
|
---|
172 | /* Check if card was just ejected */
|
---|
173 | if ((reader->card_status & CARD_INSERTED) != 0) {
|
---|
174 | log_normal("Reader: Card ejected from %s", reader->label);
|
---|
175 |
|
---|
176 | /* Clear all infos from card */
|
---|
177 | reader_common_clear_memory(reader);
|
---|
178 | }
|
---|
179 | }
|
---|
180 | }
|
---|
181 |
|
---|
182 | int reader_common_process_ecm(struct s_reader *reader, ECM_REQUEST *er)
|
---|
183 | {
|
---|
184 | int rc = 0;
|
---|
185 |
|
---|
186 | if (reader->online) {
|
---|
187 | if ((reader->caid[0] >> 8) == ((er->caid >> 8) & 0xFF)) { // TODO: move this somewhere else
|
---|
188 | client[cs_idx].last_srvid = er->srvid;
|
---|
189 | client[cs_idx].last_caid = er->caid;
|
---|
190 | client[cs_idx].last = time((time_t) 0);
|
---|
191 |
|
---|
192 | rc = cam_common_process_ecm(er);
|
---|
193 | }
|
---|
194 | }
|
---|
195 |
|
---|
196 | return rc;
|
---|
197 | }
|
---|
198 |
|
---|
199 | int reader_common_process_emm(struct s_reader *reader, EMM_PACKET *ep)
|
---|
200 | {
|
---|
201 | int rc = 0;
|
---|
202 |
|
---|
203 | if (reader->online) {
|
---|
204 | client[cs_idx].last = time((time_t) 0);
|
---|
205 |
|
---|
206 | rc = cam_common_process_emm(ep);
|
---|
207 | }
|
---|
208 |
|
---|
209 | return rc;
|
---|
210 | }
|
---|
211 |
|
---|
212 | int reader_common_cmd2card(struct s_reader *reader, uchar *cmd, ushort cmd_size, uchar *result, ushort result_max_size, ushort *result_size)
|
---|
213 | {
|
---|
214 | int rc = 0;
|
---|
215 |
|
---|
216 | if ((reader->type & R_IS_SERIAL) != 0) {
|
---|
217 | rc = (reader_serial_cmd2card(cmd, cmd_size, result, result_max_size, result_size) == 0);
|
---|
218 | }
|
---|
219 |
|
---|
220 | return rc;
|
---|
221 | }
|
---|